Use subselect in insert to temp-table - sql

I'm trying to insert a subselect in one insert to a temp table. Thing is I want to use one insert, in this insert I want to insert my sub-select to the third column of the temp table. I know that I only have 2 parameters in the first select, the trick is the third. How do I get into col 3 by using 1 insert and 1 subselect. I get the error message
Msg 120, Level 15, State 1, Procedure Stored_Procedure,
Line 24 The select list for the INSERT statement
contains fewer items than the insert list. The
number of SELECT values must match the number of INSERT columns.
This is my code.
insert into #Temp (Col01,Col02,Col03)
select X, Y from Table
where Y = CONVERT(varchar,Dateadd(DD,-0,GETDATE()),112)
and Z = '8:00' (Select X from Table
where Datum = CONVERT(varchar,Dateadd(DD,-0,GETDATE()),112)
and Z = '17:00')

number of parameter does not match to no of value
insert into #Temp (Col01,Col02,Col03)--parameters 3
select X, Y --values 2
insert into #Temp (Col01,Col02,Col03)
select X, Y , Z from Table
where Y = CONVERT(varchar,Dateadd(DD,-0,GETDATE()),112)
and Z = '8:00' (Select X from Table
where Datum = CONVERT(varchar,Dateadd(DD,-0,GETDATE()),112)
and Z = '17:00')

This is how I solved it instead.. if you want to use 1 insert with subselect you should do it this way.
insert into #ExcelPrint (Col01,Col02,Col03)
select
Z,
X as X_8,
(Select Kl_17.X from Table as Kl_17
where Kl_17.Y = CONVERT(varchar,Dateadd(DD,-0,GETDATE()),112)
and Kl_17.X = '17:00'
and Kl_17.Z = Table.Z)
as X_17
from Table
where Datum = CONVERT(varchar,Dateadd(DD,-0,GETDATE()),112)
and Z = '8:00'

Related

Is there a 2d function that will satisfy this group by requirement on two columns or is there a more sql way to do?

I have a table and need to do a group by over two columns or a function of those that yields the expected grouping criteria. This became surprisingly an interesting math challenge but I am also happy to see how to solve it in a standard SQL solution.
I have the following table:
create table temp (a integer, x integer, y integer);
insert into temp values (3, 0, 1);
insert into temp values (3, 1, -1);
insert into temp values (4, 0, 1);
insert into temp values (4, 1, -1);
insert into temp values (4, 0, -1);
insert into temp values (4, 1, 1);
I'd like to group together rows:
1 and 2
3 and 4
5 and 6
Therefore, the select would be:
select a
from temp
group by a, f(x, y)
For that I need a function f(x, y) built on available SQLite integer operators i.e. *, +, -, / therefore I need a function such that:
f(0, 1) = f(1, -1) and
f(0, -1) = f(1, 1)
I have tried multiple possibilities but can't figure out such grouping function ... any clever ideas? :)
Would there be an alternative SQL solution for this problem?
Well, you can define such a "function" using a case expression:
(case when x = 0 and y = 1 then 1
when x = 1 and y = -1 then 1
when x = 0 and y = -1 then 2
when x = 1 and y = 1 then 2
end)
If you want an arithmetic expression:
(2 * x * y - y)

Insert into a table based on flag values of other table

I have two tables
src (party_key,is_NRA,is_DOM,is_PEP)
and
dest(party_key,aml_type,aml_name)
What I want to do is -
If src.is_NRA = 1, then insert into dest values (src.party_key,'NRA','Is NRA')
If src.is_DOM = 1, then insert into dest values (src.party_key,'DOM','Is DOM')
.
.
One row in src table can have all 3 flags as '1'. In that case, I want to insert 3 separate rows in dest table.
How can I implement this in SQL?
Here you go
INSERT INTO dest(party_key,aml_type,aml_name)
SELECT src.party_key, 'NRA', 'Is NRA' FROM src WHERE src.is_NRA = 1;
INSERT INTO dest(party_key,aml_type,aml_name)
SELECT src.party_key, 'DOM', 'Is DOM' FROM src WHERE src.is_DOM = 1;
INSERT INTO dest(party_key,aml_type,aml_name)
SELECT src.party_key, 'PEP', 'Is PEP' FROM src WHERE src.is_PEP = 1;
INSERTing with three separate SELECTs may be fine for your purposes, but that's three separate table scans. INSERTing with one table scan is possible if you UNPIVOT (reference: http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx):
INSERT INTO
dest (
party_key,
aml_type,
aml_name
)
SELECT
party_key,
RIGHT([type], 3),
'Is ' + RIGHT([type], 3)
FROM
src
UNPIVOT (
flag FOR [type] IN (
is_NRA,
is_DOM,
is_PEP
)
) unpvt
WHERE
flag = 1
Am I missing something?
IF src.is_dom = 1 AND src.is_NRA = 1 AND src.is_PEP = 1,
THEN
INSERT INTO dest (party_key, aml_type, aml_name)
VALUES (src.party_key, 'DOM', 'Is DOM'), (src.party_key,'NRA','Is NRA'), (src.party_key,'PEP','Is PEP')

possible to add a row number to a SELECT clause that is not order dependent

If I have this fiddle
CREATE TABLE temp
(
y char(9),
x char(9)
);
insert into temp (x, y) values ('j', 'hello');
insert into temp (x, y) values ('j', 'world');
insert into temp (x, y) values ('q', 'foo');
insert into temp (x, y) values ('q', 'bar');
select
x
,y
from temp
I'd like to have a row number included in the SELECT clause. So the result would look like this:
x y r
j hello 1
j world 2
q foo 3
q bar 4
I don't believe Row_number() over will work as this requires an Order and I do not want to change the order from the SELECT * FROM. Also do not want to an an identity column to the client db table
Is this possible in SQL-Server?
If you're okay with r being non-deterministic (in other words it may not work the same every time):
select
x
,y
, r = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
from temp
order by r;
To see even a very simple case where it doesn't work the same way:
CREATE TABLE temp
(
y char(9) PRIMARY KEY,
x char(9)
);
And of course if you want the order to be random:
select
x
,y
, r = ROW_NUMBER() OVER (ORDER BY NEWID())
from temp
order by r;

MySQL: Is it possible to return a "mixed" dataset?

I'm wondering if there's some clever way in MySQL to return a "mixed/balanced" dataset according to a specific criterion?
To illustrate, let's say that there are potential results in a table that can be of Type 1 or Type 2 (i.e. a column has a value 1 or 2 for each record). Is there a clever query that would be able to directly return results alternating between 1 and 2 in sequence:
1st record is of type 1,
2nd record is of type 2,
3rd record is of type 1,
4th record is of type 2,
etc...
Apologies if the question is silly, just looking for some options. Of course, I could return any data and do this in PHP, but it does add some code.
Thanks.
Something like this query should do:
Select some_value, x, c
From
(
Select
some_value, x,
Case When x=1 Then #c1 Else #c2 End As c,
#c1 := Case When x=1 Then #c1+2 Else #c1 End As c1,
#c2 := Case When x=2 Then #c2+2 Else #c2 End As c2
From test_data, (Select #c1:=0, #c2:=1) v
Order By some_value
) sub
Order By c
It assigns unique even numbers to x=0, and odd numbers to x=1, and uses these values as sort criteria.
It returns
some_value x c
A 1 0
X 2 1
B 1 2
Y 2 3
C 1 4
Z 2 5
for the following test-data:
Create Table test_data (
some_value VARCHAR(10),
x INT
);
Insert Into test_data Values('A', 1);
Insert Into test_data Values('B', 1);
Insert Into test_data Values('C', 1);
Insert Into test_data Values('Z', 2);
Insert Into test_data Values('Y', 2);
Insert Into test_data Values('X', 2);
Within the alternating rule values are sorted by some_value, you can change this in the inner select, or add your conditions there.
If there are more values of a certain type (1 or 2), you get them after the rest (1 2 1 2 2 2).
You can use IF function as a part of your SELECT statement to change columns, but I'm not sure how to make is alternate automatically between two columns. If you however find proper condition this will work for you
SELECT IF(condition, first_column, second_column) FROM your_table
first_column and second_column can be of different type, for example:
SELECT IF(id > 10, name, status_id) FROM clients
works well when name is a VARCHAR and status_id is an INT

T-Sql Query - Get Unique Rows Across 2 Columns

I have a set of data, with columns x and y. This set contains rows where, for any 2 given values, A and B, there is a row with A and B in columns x and y respectivly and there will be a second row with B and A in columns x and y respectivly.
E.g
**Column X** **Column Y**
Row 1 A B
Row 2 B A
There are multiple pairs of data in
this set that follow this rule.
For every row with A, B in Columns
X and Y, there will always be a
row with B, A in X and Y
Columns X and Y are of type int
I need a T-Sql query that given a set with the rules above will return me either Row 1 or Row 2, but not both.
Either the answer is very difficult, or its so easy that I can't see the forest for the trees, either way it's driving me up the wall.
Add to your query the predicate,
where X < Y
and you can never get row two, but will always get row one.
(This assumes that when you wrote "two given values" you meant two distinct given values; if the two values can be the same, add the predicate where X <= Y (to get rid of all "reversed" rows where X > Y) and then add a distinct to your select list (to collapse any two rows where X == Y into one row).)
In reply to comments:
That is, if currently your query is select foo, x, y from sometable where foo < 3; change it to select foo, x, y from sometable where foo < 3 and x < y;, or for the the second case (where X and Y are not distinct values) select distinct foo, x, y from sometable where foo < 3 and x <= y;.
This should work.
Declare #t Table (PK Int Primary Key Identity(1, 1), A int, B int);
Insert into #t values (1, 2);
Insert into #t values (2, 1);
Insert into #t values (3, 4);
Insert into #t values (4, 3);
Insert into #t values (5, 6);
Insert into #t values (6, 5);
Declare #Table Table (ID Int Primary Key Identity(1, 1), PK Int, A Int, B Int);
Declare #Current Int;
Declare #A Int;
Insert Into #Table
Select PK, A, B
From #t;
Set #Current = 1;
While (#Current <= (Select Max(ID) From #Table) Begin
Select #A = A
From #Table
Where ID = #Current;
If (#A Is Not Null) Begin
Delete From #Table Where B = #A;
If ((Select COUNT(*) From #Table Where A = #A) > 1) Begin
Delete From #Table Where ID = #Current;
End
End
Set #A = Null;
Set #Current = #Current + 1;
End
Select a.*
From #tAs a
Inner Join #Table As b On a.PK = b.PK
SELECT O.X, O.Y
FROM myTable O
WHERE EXISTS (SELECT X, Y FROM myTable I WHERE I.X = O.Y AND I.Y = O.X)
I have not tried this. But, this should work.
To get the highest and lowest of each pair, you could use:
(X+Y+ABS(X-Y)) / 2 as High, (X+Y-ABS(X-Y)) / 2 as Low
So now use DISTINCT to get the pairs of them.
SELECT DISTINCT
(X+Y+ABS(X-Y)) / 2 as High, (X+Y-ABS(X-Y)) / 2 as Low
FROM YourTable