I have a SELECT INTO #tTable SELECT CASE WHEN condition THEN value1 ELSE value2 query.
When a particular condition is verified I have to insert into #tTable 2 rows instead of 1 that differ each other only for 1 column.
I resolved this problem in this way:
Insert into #tTable a foo row with value for my column v1v2
Insert into #tTable value1 where col = v1v2
Insert into #tTable value2 where col = v1v2
Delete from #tTable where col = v1v2
Is there a better and more performance way to do this? Is there a way to insert 2 rows in an INSERT INTO #table SELECT CASE WHEN statement?
Example:
INSERT INTO #tTable (col1, col2, col3)
SELECT T.col1, T.col2, CASE WHEN T.col1 > T.col2 THEN v1v2
WHEN T.col1 = T.col2 THEN value1 ELSE value2 END
FROM Table1 as T;
INSERT INTO #tTable (col1, col2, col3)
SELECT T.col1, T.col2, value1
FROM Table1 as T
WHERE T.col3 = v1v2;
INSERT INTO #tTable (col1, col2, col3)
SELECT T.col1, T.col2, value2
FROM Table1 as T
WHERE T.col3 = v1v2;
DELETE FROM #tTable
WHERE col3 = v1v2;
I have to insert 2 rows (one with value1 and other with value2) on case when T.col1 > T.col2
EDIT:
Actually, my query is like this:
INSERT INTO #tTable (col1, col2, col3)
SELECT T.col1, T.col2,
CASE WHEN condition1 AND condition2 AND condition3 THEN value1
WHEN condition4 AND condition5 AND condition6 THEN value2
WHEN condition7 AND condition8 AND condition9 THEN v1v2 END
FROM Table1 as T
You can't generate another row with a CASE, you will have to use UNION ALL or an additional INSERT. The simplest way I see it is with a UNION ALL, repeating the condition for v1 + v2 on each SELECT:
INSERT INTO #tTable (
col1,
col2,
col3)
SELECT
V.Col1,
V.Col2,
col3 = V.value1
FROM
Table1 AS V
WHERE
(condition1 AND condition2 AND condition3) OR -- value1 condition
(condition7 AND condition8 AND condition9) -- shared condition
UNION ALL
SELECT
V.Col1,
V.Col2,
col3 = V.value2
FROM
Table1 AS V
WHERE
(condition4 AND condition5 AND condition6) OR -- value2 condition
(condition7 AND condition8 AND condition9) -- shared condition
If your conditions are bound to change or are complex, you can write them only once if you place them on a CTE and reference their output:
;WITH DataWithConditions AS
(
SELECT
T.Col1,
T.Col2,
T.Value1,
T.Value2,
Condition = CASE
WHEN condition1 AND condition2 AND condition3 THEN 1
WHEN condition4 AND condition5 AND condition6 THEN 2
WHEN condition7 AND condition8 AND condition9 THEN 3 END
FROM
Table1 AS T
)
INSERT INTO #tTable (
col1,
col2,
col3)
SELECT
V.Col1,
V.Col2,
col3 = V.value1
FROM
DataWithConditions AS V
WHERE
V.Condition IN (1, 3)
UNION ALL
SELECT
V.Col1,
V.Col2,
col3 = V.value2
FROM
DataWithConditions AS V
WHERE
V.Condition IN (2, 3)
You can try UNION ALL to incorporate the second column's value as ROW as shown below-
INSERT INTO #tTable (col1, col2, col3)
SELECT T.col1, T.col2,
CASE
WHEN T.col1 > T.col2 THEN value1 -- Column name may be v1v2
WHEN T.col1 = T.col2 THEN value1
ELSE value2
END
FROM Table1 AS T
UNION ALL
SELECT T.col1, T.col2,value2 -- Value2 I guess the 2nd column
FROM Table1 AS T WHERE T.col1 > T.col2
Related
I have query which will group column 1 and 2 and calculate count for column3
(select col1, col2, count(col3)
from table1
group by col1,col2
Having count(col3) < 50)
But I want to display all fields values for col3 where count(col3) < 50 . Can you help me with this? Thank you
Try this:
select col1, col2, col3, t.cnt
from (
select col1, col2, col3,
count(col3) over (partition by col1, col2) AS cnt
from table1 ) as t
where t.cnt < 50
The idea is to use windowed version of COUNT instead of GROUP BY. COUNT(col3) OVER (PARTITION BY col1, col2) returns the count of col3 occurrences per col1, col2 for every row of table1. You can filter out col1, col2 slices having a count of 50 or more in an outer query.
You can also use something like this:
select t.col1, t.col2, t.col3
from table1 t
where
EXITS(select 1 from table1 t1 where t.col1 = t1.col1 and t.col2 = t.col2 having count(t1.col3) > 50)
or something like this:
select t.col1, t.col2, t.col3
from table1 t
inner join (select t1.col1, t1.col2, count(t1.col3) from table1 t1
group by t1.col1, t1.col2 having count(t1.col3) > 50) x
on t.col1 = x.col1 and t.col2 = x.col2
create table a ( col1 int, col2 int)
create table b (col1 int,col2 int)
insert b
select 1,2
union
select 1,2
insert a
select 1,2
union
select 2,2
Expected o/p (need to join two tables and then get true for first match, false for second match and if not match also false)
1,2,T
1,2,F
2,2,F
SELECT col1, col2,
CASE WHEN (rownumber = 1 AND othercol is not null)
THEN 'T' ELSE 'F' END col3
FROM
(
Select a.col1, a.col2,b.col1 othercol, ROW_NUMBER() OVER(Partition by a.col1 ,a.col2 order by a.col1,a.col2) rownumber
from #a a
LEFT JOIN #b b ON a.col1 = b.col1 AND a.col2 = b.col2
) t
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
My SQL kung-fu is not strong. I want to know if I can identify which value of a WHERE clause is incorrect.
So say I execute the following SQL statement....
SELECT col1, col2, col3 FROM dbo.myTable WHERE col1 = 'ABC' and col2 = 123
I want to be able to identify either that the value 'ABC' for col1 doesn't exist OR that the value 123 for col2 does not exist.
This would be within a single query, as I want to avoid two queries if possible.
Where I execute the first, and if rows exist then I execute the second if no rows then I can derive that col2 is wrong.
SELECT col1, col2, col3 FROM dbo.myTable WHERE col1 = 'ABC'
SELECT col1, col2, col3 FROM dbo.myTable WHERE col1 = 'ABC' and col2 = 123
I have considered
SELECT 1 as qRow, col1, col2, col3 FROM dbo.myTable WHERE col1 = 'ABC'
UNION
SELECT 2 as qRow, col1, col2, col3 FROM dbo.myTable WHERE col1 = 'ABC' and col2 = 123
and based on the qRow value i can determine which value is missing within the table, but wanted to now if there was any other solution
If you want to find where col1 is not ABC or col2 is not 123, you can do this:
SELECT col1 ,
col2 ,
col3
FROM dbo.myTable
WHERE col1 <> 'ABC'
OR col2 <> 123
Are you looking for something like
SELECT col1, col2, col3,
CASE
WHEN col1 = 'ABC' and col2 = 123 THEN 'both_true'
WHEN col1='ABC' THEN 'col1_true'
ELSE 'col2_true'
END AS value_check
FROM dbo.myTable WHERE col1 = 'ABC' or col2 = 123
I think probably you can use NOT EXISTS like
SELECT col1, col2, col3
FROM dbo.myTable
WHERE NOT EXISTS ( select 1 from dbo.myTable
where col1 = 'ABC' or col2 = 123)
SELECT col1, col2, col3, case when col1 <> 'ABC' then 'X' end as 'MissingCol1Abc',
case when col2 <> 123 then 'X' end as MissingCol2
FROM dbo.myTable
WHERE col1 = 'ABC' OR col2 = 123
Or did you mean you want to know when the column is null?
SELECT col1, col2, col3, case when is null col1 then 'X' end as 'MissingCol1Abc',
case when col2 is null then 'X' end as MissingCol2
FROM dbo.myTable
WHERE col1 = 'ABC' OR col2 = 123
If you use an OR instead of AND you could add a CASE statement to show the matching column:
SELECT col1, col2, col3,
CASE WHEN col1 = 'ABC' THEN 'True' ELSE 'False' END as Col1Match,
CASE WHEN col2 = '123' THEN 'True' ELSE 'False' END as Col2Match
FROM dbo.myTable
WHERE col1 = 'ABC' OR col2 = 123
Sample SQL Fiddle
You will see in the sample fiddle, that rows are only returned where one or both items match.
I need to make a trigger that, upon an insert into table1, checks if the same values from 3 columns in table2 match, if not it inserts that row into table2. If there is a match it then updates the row that matches. Here's what I've gathered so far, but it doesn't do the IF EXISTS check I need it to. I'm not certain how exactly to structure it in this case due to never having worked with triggers.
CREATE TRIGGER Trigger_Name on Table_Name
FOR INSERT
AS
BEGIN
INSERT INTO
TABLE 2
(
Col1,
Col2,
Col3,
Col4
)
SELECT
(
Col1,
Col2,
Col3,
Col4
)
FROM
INSERTED
GO
The IF EXISTS criteria need to see if table1.col1=table2.col1, table1.col2=table2.col2, table1.col3,table2.col3
Using SQL server 2008. Any help is much appreciated
UPDATE table2
SET col1 = inserted.col1
, col2 = inserted.col2
, col3 = inserted.col3
, col4 = inserted.col4
FROM table2
INNER
JOIN inserted
ON inserted.col1 = table2.col1
AND inserted.col2 = table2.col2
AND inserted.col3 = table2.col3
;
INSERT INTO table2 (col1, col2, col3, col4)
SELECT col1
, col2
, col3
, col4
FROM inserted
WHERE NOT EXISTS (
SELECT *
FROM table1
WHERE col1 = inserted.col1
AND col2 = inserted.col2
AND col3 = inserted.col3
)
;