I need to query for a dataset in SQL Server and have one of the return columns based on either one of two subqueries. The control of which subquery is from a value of another column in the query. Some basic pseudo query language of what I'm trying to do:
select col1, col2, col3,
if col3 = 1
(select count(*) from table2 where table2.col1 = table1.col1) as count1
else
(select count(*) from table3 where table3.col1 = table1.col1) as count1
from table1
What's the best way to accomplish this?
SELECT col1, col2, col3,
CASE WHEN col3 = 1 THEN
(SELECT count(*)
FROM table2
WHERE table2.col1 = table1.col1)
ELSE
(SELECT count(*)
FROM table3
WHERE table3.col1 = table1.col1)
END AS count1
FROM table1
You should declare a variable and SELECT column col3 into it.
Or you could do a CASE...WHEN block.
Related
I have below table from which I want to return records based on the precedence of the column value.
col1
col2
Col3
1
val1
Master
1
val1
Distributor
2
val2
Master
3
val3
Distributor
3
val3
Master
precedence
type
1
Master
2
Distributor
Here I have type Master as precedence 1 and type Distributor has precedence 2. So, if Col1 and Col2 values are repeated for type (Master and Distributor) then I want to return the row for Master as it take precedence over Distributor.
Output:
The result I want to get is:
col1
col2
Col3
1
val1
Master
2
val2
Master
3
val3
Master
Please someone help me write the SQL query for this output.
You can use the WITH TIES option in concert with row_number()
Select top 1 with ties *
From YourTable
Order By row_number() over (partition by col1,col2 order by col3 desc)
If two tables
Select top 1 with ties A.*
From YourTable A
Join SeqTable B on A.Col3=B.Type
Order By row_number() over (partition by col1,col2 order by B.precedence)
You can use the INNER JOIN and analytical function as follows:
select col1, col2, col3 from
(select t1.*,
row_number() over (partition by t1.col1, t1.col2 order by t2.precedence) as rn
from table1 t1 join table2 t2 on t1.col3 = t2.precedence) t
where rn = 1
Perhaps it is possible to optimize, first I do aggregation with a minimum, then I merge the table to pull out type and then I select three fields from all this
SELECT
col1,
col2,
type
FROM (
SELECT *
FROM precedence_table
INNER JOIN
(
SELECT
col1,
col2,
Min(precedence_table.precedence) AS top
FROM `my_table`
LEFT JOIN `precedence_table`
ON my_table.col3 = precedence_table.type
GROUP BY my_table.col1, my_table.col2) AS agregated
HAVING precedence = agregated.top) AS queried
I want to INSERT INTO by more than one value at a time, I did this by doing the following:
INSERT INTO table_1(col_1,col_2,col_3)
SELECT col_1, col2, (SELECT col3 FROM table_3)
FROM table_2
But col3 from table_3 is a datetime format, while col3 from table_1 needs an integer value. I did this by doing the following:
CAST(CONVERT(varchar(10),(SELECT col3 FROM table_3),112)AS int)
When I run this I get a more than one result in a subquery error. I have really no idea whatsoever on how to fix this. Hopefully you do.
Thank you in advance.
INSERT INTO table_1(col_1,col_2,col_3)
SELECT col_1, col2, (CAST(CONVERT(varchar(10),(SELECT top 1 col3 FROM table_3),112)AS int))
FROM table_2
You need to use top 1 to select 1 row
Well, I think the error says it all. You have to limit the inner query somehow with WHERE condition, with TOP or with MAX(col3) for example. Depends WHICH col3 you want.
You need to join table_2 to table_3. Not sure what your database structure is, but it should be something like this:
INSERT INTO table_1(col_1,col_2,col_3)
SELECT t2.col_1, t2.col2, t3.col3
FROM table_2 t2
INNER JOIN table_3 t3 on t3.t2id = t2.id
The alternative is to use TOP 1, to just return 1 record in the sub-query - but I would not recommend this as it may not be the value you want:
INSERT INTO table_1(col_1,col_2,col_3)
SELECT col_1, col2, (SELECT top 1 col3 FROM table_3)
FROM table_2
You can use CTE to prepare your data :
;WITH MyData (col1, col2, col3)
AS
(
SELECT col_1, col2, CAST(CONVERT(varchar(10),(col3),112)AS int)
FROM table_2 JOIN table_3 ON <join condition>
)
INSERT INTO table_1(col_1,col_2,col_3)
SELECT col_1, col2, col3
FROM MyData
Pls try below query :
INSERT INTO table_1(col_1,col_2,col_3)
SELECT col_1, col2, isnull((SELECT TOP 1 cast(col3 as int) FROM table_3),0)
FROM table_2
I have an sql query like this
Select col1, (select abc from table2 where def=1) as col2
From Table1 inner join table3 on Table1.id = table3.id
Where col2 = 4
The problem is that the where condition doesn't work. I get an error saying
Invalid column name 'col2'
Kindly help me fix this sql query.
Thanks in advance
You can define it in a CROSS APPLY and then reference in the SELECT and WHERE
SELECT col1,
col2
FROM Table1
INNER JOIN table3
ON Table1.id = table3.id
CROSS APPLY (SELECT abc
FROM table2
WHERE def = 1) C(col2)
WHERE col2 = 4
Using a CTE (Common Table Expression):
WITH SubQuery AS (Col2) {
SELECT
ABC
FROM
table2
WHERE
def = 1
}
SELECT
T.Col1,
S.Col2
FROM
SubQuery S,
Table1 T
INNER JOIN table3 t3
ON T.id = t3.id
WHERE
S.Col2 = 4
Although I must say I agree with the first comment - this makes no sense since your subquery is not correlated (joined) to the rest of your query...
I am a complete beginner with SQL, and I have to turn a query like this one:
SELECT col1, col2, col3 FROM db1
LEFT OUTER JOIN (SELECT col1, col2 FROM db2 WHERE some_conditions) AS query1
ON (query1.col1 = col2)
Into a query like this one:
SELECT col1, col2, col3 FROM db1
if col1 = 1
LEFT OUTER JOIN (SELECT col1, col2 FROM db2 WHERE some_conditions) AS query1
ON (query1.col1 = col2)
else
LEFT OUTER JOIN (SELECT col1, col2 FROM db2 WHERE some_other_conditions) AS query1
ON (query1.col1 = col2)
But the latter obviously doesn't work in SQL Server. What would be the proper format for a query like this?
You could use a complex on clause:
select *
from db1
left join
db2
on db1.col1 = db2.col2
and (
(db1.col1 = 1 and some_conditions)
or (db1.col1 <> 1 and some_other_conditions)
)
Using or, you can use one codition set in one case, and another condition set in another case.
I have a SQL Select and I am not sure how I can achieve this. I am checking two fields to see if any of those fields are in a list. So like,
Select * from MyTable where col1 or col2 in (select col3 from OtherTable where ID=1)
I tried
Select * from MyTable where
col1 in (select col3 from OtherTable where ID=1)
or col2 in (select col3 from OtherTable where ID=1)
But, this returns the records that match first condition (only returns col1, but not col2) for some reasons.
Try this -
Select * from MyTable where
(col1 in (select col3 from OtherTable where ID=1))
or
(col2 in (select col3 from OtherTable where ID=1) )
if you're subquery is the same for both columns, i'd throw it into a cte, then do a left outer join on the cte on col1 and col2, then do your where statement.
;with c3 as
(
select col3
from OtherTable
where ID=1
)
select m.*
from MyTable m
left outer join c3 as c1
on m.col1=c1.col3
left outer join c3 as c2
on m.col2=c2.col3
where
(c1.col3>'')
or (c2.col3>'')
if a blank varchar that isn't null is a viable option, change your where clauses to >=.
SELECT t.*
FROM MyTable t
INNER JOIN (
select col3
from OtherTable
where ID=1
) sel ON sel.col3 IN (t.col1, t.col2)