Does anybody know how can we get the list of all the columns in all the tables which are varchar?
i need it in below format:
<column_name> <table_name>
i tried this:
select o.name [TableName], c.name [ColumnName] from sysobjects o
inner join syscolumns c on c.id = o.id inner join systypes t
on t.usertype = c.usertype where o.type = 'U' and o.name in ("MYTABLE")
but the above gives the list of all columns.
if i can find a way then i can put all the table names inside last braces.
You can use where systypes.name = 'varchar', or systypes.type = 39, or syscolumn.type = 39 to narrow your query to just varchar columns.
select o.name, c.name from sysobjects o, syscolumns c
where o.id = c.id
and c.type = 39
and o.type = "U"
Related
Here is the code i am using to filter rows with a variable from single column and Its working:
cur.execute("SELECT * FROM Table1 WHERE item1 LIKE ?", ('%'+item_name+'%', ))
n = cur.fetchall()
But i want to filter rows with one variable from multiple columns.
For example: Table has three columns as item1, item2 and item3. I want to filter rows as select * from table1 where item1, item2 and item3.
If it is possible, please let me know How to do?
You can join the table to this query:
SELECT '%' || ? || '%' AS item_name
on the conditions that you want, like this:
SELECT t1.*
FROM Table1 t1 INNER JOIN (SELECT '%' || ? || '%' AS item_name) t2
ON t1.item1 LIKE t2.item_name OR t1.item2 LIKE t2.item_name OR t1.item3 LIKE t2.item_name
and your code will be:
cur.execute("SELECT t1.* FROM .....", (item_name, ))
imagine these two tables.
Table A
ID col1 col2 col3
1 foo baz bar
2 ofo zba rba
3 oof abz abr
Table B
A_ID field_name field_value
1 first Jon
1 last Doe
2 first Adam
2 last Smith
etc..
Now I would like to have a query (current one looks like this)
SELECT
a.id,
a.col1,
a.col2,
(SELECT field_value FROM B WHERE A_ID = a.id AND field_name = 'first') as first_name,
(SELECT field_value FROM B WHERE A_ID = a.id AND field_name = 'last') as last_name
FROM A a
WHERE (SELECT COUNT(*) FROM B WHERE A_ID = a.id) = 2;
This query is working. What I would like to achieve would be something like this.
SELECT
a.id,
a.col1,
a.col2,
(SELECT field_value FROM b WHERE b.field_name = 'first') as first_name,
(SELECT field_value FROM b WHERE b.field_name = 'last') as last_name
FROM
A a,
(SELECT field_value, field_name FROM B WHERE A_ID = a.id) b
WHERE (SELECT COUNT(*) FROM b) = 2;
How would my approach look correctly? Is there any other way to get rid of the multiple queries of the table B?
Thank you!
I would replace your correlated subqueries with joins:
SELECT
a.id,
a.col1,
a.col2,
b1.field_value AS fv1,
b2.field_value AS fv2
FROM A a
LEFT JOIN B b1
ON a.id = b1.A_ID AND b1.field_name = 'first'
LEFT JOIN B b2
ON a.id = b2.A_ID AND b2.field_name = 'last';
This answer assumes that a left join from a given A record would only match at most one record in the B table, which, however, is a requirement anyway for your correlated subqueries to only return a single value.
I am attempting to use a subquery in a left join condition, but am getting an error message that reads: "Error in SQL statement: AnalysisException: Table or view not found: TableD;" and points to the FROM TableD D2 statement in my subquery.
SELECT D1.Code, D1.Description, C.InstanceKey
FROM TableA A
INNER JOIN TableB B
ON A.Key = B.Key
INNER JOIN TableC C
ON B.DetailKey = C.DetailKey
LEFT JOIN TableD D1
ON C.InstanceKey = D1.InstanceKey
AND D1.RankCnt = (SELECT MIN(D2.RankCnt)
FROM TableD D2
WHERE C.InstanceKey = D2.InstanceKey);
If I remove the subquery and hardcode D1.RankCnt = [anyValidRankCnt], the query runs without issue.
This question has also been posted on the Databricks Community Forum at https://forums.databricks.com/questions/14588/why-is-subquery-in-left-join-causing-error-msg.html.
I'm not sure if that particular type of correlated subquery is supported in Spark at this time, although I was able to rewrite it in a couple of different ways, including using ROW_NUMBER. Please check these queries are semantically equivalent to yours with your data:
%sql
-- Rewrite 1: CTE
WITH cte AS
(
SELECT D1.Code, D1.Description, C.InstanceKey, ROW_NUMBER() OVER ( PARTITION BY c.InstanceKey ORDER BY D1.RankCnt ) xrank
FROM TableA A
INNER JOIN TableB B
ON A.Key = B.Key
INNER JOIN TableC C
ON B.DetailKey = C.DetailKey
LEFT JOIN TableD D1
ON C.InstanceKey = D1.InstanceKey
)
SELECT *
FROM cte
WHERE xrank = 1
-- Rewrite 2: subquery
SELECT x.Code, x.Description, C.InstanceKey
FROM TableA A
INNER JOIN TableB B
ON A.Key = B.Key
INNER JOIN TableC C
ON B.DetailKey = C.DetailKey
LEFT JOIN
(
SELECT D1.InstanceKey, D1.Code, D1.Description, D1.RankCnt
FROM TableD D1
INNER JOIN
(
SELECT InstanceKey, MIN(RankCnt) RankCnt
FROM TableD
GROUP BY InstanceKey
) D2 ON D1.InstanceKey = D2.InstanceKey
AND D1.RankCnt = D2.RankCnt
) x
ON c.InstanceKey = x.InstanceKey;
-- Rewrite 3: UNION ALL
SELECT D1.Code, D1.Description, C.InstanceKey
FROM TableA A
INNER JOIN TableB B
ON A.Key = B.Key
INNER JOIN TableC C
ON B.DetailKey = C.DetailKey
INNER JOIN TableD D1
ON C.InstanceKey = D1.InstanceKey
INNER JOIN
(
SELECT D2.InstanceKey, MIN(D2.RankCnt) RankCnt
FROM TableD D2
GROUP BY D2.InstanceKey
) x ON C.InstanceKey = x.InstanceKey
AND D1.RankCnt = x.RankCnt
UNION ALL
SELECT NULL AS Code, NULL AS Description, C.InstanceKey
FROM TableA A
INNER JOIN TableB B
ON A.Key = B.Key
INNER JOIN TableC C
ON B.DetailKey = C.DetailKey
WHERE NOT EXISTS
(
SELECT *
FROM TableD D1
WHERE C.InstanceKey = D1.InstanceKey
);
Is it possible to create a typed query that produces the following SQL?
SELECT A.*
FROM schema1.Table1 A
INNER JOIN (SELECT DISTINCT column1, column2 FROM schema1.Table2) B ON A.column1 = B.column1
You can't join a sub select with a typed API, the easiest way to implement this would be to use a CustomJoin, e.g:
var table1 = db.GetTableName<Table1>();
var q = db.From<Table1>()
.CustomJoin($#"INNER JOIN
(SELECT DISTINCT column1, column2 FROM schema1.Table2) B
ON {table1}.column1 = B.column1");
Can you give me a query,that converts the rows values which are of type varchars into a single column with any delimiter.
e.g
table with 2 columns
col1 |col2
1 | m10
1 | m31
2 | m20
2 | m50
now i want output as
col1| col2
1|m10:m31
2|m20:m50
Do you always have matched pairs, no more no less?
select
col1,
count(*)
from table
group by col1
having count(*) <> 2
would give you zero results?
if so, you can just self join...
declare #delimiter varchar(1)
set #delimiter = :
select
t1.col1, t1.col2 + #delimiter + t2.col2
from tablename t1
inner join tablename t2
on t1.col1 = t2.col1
and t1.col2 <> t2.col2
One way to do that is using cursors.
With the cursor you can fetch a row at a time!
Pseudo-code would be:
if actual_col1 = last_col1
then col2_value = col2_value + actual_col2
else
insert into #temptable value(col1, col2_value)
col2_value = actual_col2
end
Check HERE to know how to use them.
use this solution :
SELECT list(col2, ':') as col2 FROM table_name group by col1 ;
Please use the below logic, the table #t1 will be the final table.
create table #t123(a char(2), b char(2))
go
create table #t1(a char(2), c char(100) default '')
go
Insert into #t123 values ('a','1')
Insert into #t123 values ('a','2')
Insert into #t123 values ('a','3')
Insert into #t123 values ('b','1')
Insert into #t123 values ('c','1')
Insert into #t123 values ('d','1')
Insert into #t123 values ('d','1')
go
insert into #t1 (a) Select distinct a from #t123
go
Select distinct row_id = identity(8), a into #t1234 from #t123
go
Declare #a int, #b int, #c int, #d int, #e int, #f char(2), #g char(2), #h char(2)
Select #a =min(row_id), #b=max(row_id) from #t1234
While #a <= #b
Begin
Select #f = a , #h = '', #g = '' from #t1234 where row_id = #a
Update #t1 set c = '' where a = #f
Select row_id = identity(8), b into #t12345 from #t123 where a = #f
Select #c =min(row_id), #d=max(row_id) from #t12345
While #c <= #d
begin
Select #g = b from #t12345 where row_id = #d
Update #t1 set c = #g +' '+ c where a = #f --change delimiter
Select #d = #d-1
End
Drop table #t12345
Select #a = #a+1
End
go
Select * from #t1 -- final table with transposed values