SQL - CASE WHEN troubles - sql

Running into an issue with a CASE WHEN statement. Sample script below:
SELECT
CASE WHEN Column1 = "Example 1" THEN "Name 1"
WHEN Column1 = "Example 2" THEN "Name 2"
WHEN Column1 = "Example 3" THEN "Name 3"
WHEN Column1 = "Example 3" AND Column2 IN ("Sample1", "Sample2") THEN "Name4"
WHEN Column1 = "Example 3" AND Column2 IN ("Sample3", "Sample4") THEN "Name5"
ELSE "-" END AS Name,
[aggregation language that doesn't affect the script]
FROM Table1
GROUP BY Name
HAVING Name IN ("Name1", "Name2", "Name3", "Name4", "Name5"
ORDER BY Name ASC
The issue I'm having is that when executing the script "Name1", "Name2", and "Name3" all pull (and pull accurately), but "Name4" and "Name5" won't pull at all, presumably because they share a condition with "Name3" (Column1 = "Example3").
Essentially, I'm trying to pull both the aggregate that is "Name3" and it's components that are "Name4" and "Name5".
One way to think about it is that "Name3" is the NFL and "Name4" and "Name5" are the AFC and NFC, respectively. Because I'm pulling in the NFL with the condition {Column1 = "Example3"}, it won't pull in the AFC and NFC, despite having a second required "AND" condition.
Would LOVE if someone could help here. I've tried using parentheses, changing the order of the WHENs...no luck.
Thanks in advance!

My recommendation would be to change the ordering of your cases:
SELECT
CASE WHEN Column1 = "Example 1" THEN "Name 1"
WHEN Column1 = "Example 2" THEN "Name 2"
WHEN Column1 = "Example 3" AND Column2 IN ("Sample1", "Sample2") THEN "Name4"
WHEN Column1 = "Example 3" AND Column2 IN ("Sample3", "Sample4") THEN "Name5"
WHEN Column1 = "Example 3" THEN "Name 3"
ELSE "-" END AS Name,
[aggregation language that doesn't affect the script]
FROM Table1
GROUP BY Name
HAVING Name IN ("Name1", "Name2", "Name3", "Name4", "Name5"
ORDER BY Name ASC
With your current ordering, If "Name4" or "Name5" is true, "Name 3" will always be true, so it will get executed first. With the modified ordering, "Name 3" will be true only if "Name4" and "Name5" come out to be false. Make sense?

Would LOVE if someone could help here. I've tried using parentheses, changing the order of the WHENs...no luck.
You're not being entirely honest, are you?
http://sqlfiddle.com/#!6/11381/3/0 -- a simple switch of the WHEN conditions fixes your little problem. The lesson here is that testing stops at the first condition that's true.

For "Name 3", you need to exclude the conditions of "Name 4" and "Name 5":
CASE WHEN Column1 = "Example 1" THEN "Name 1"
WHEN Column1 = "Example 2" THEN "Name 2"
WHEN Column1 = "Example 3"
AND Column2 NOT IN ("Sample1", "Sample2", "Sample3", "Sample4") THEN "Name 3"
WHEN Column1 = "Example 3" AND Column2 IN ("Sample1", "Sample2") THEN "Name4"
WHEN Column1 = "Example 3" AND Column2 IN ("Sample3", "Sample4") THEN "Name5"
ELSE "-" END AS Name,
case when returns from the first matching condition and then ignores the rest, so you need to make the earlier condition narrower. Alternatively, you could put the Name4/5 conditions before the Name 3 condition.

Related

Use column value as column name when inserting (Clickhouse)

I have a source table:
Data
122435
2912
32
I want to select data from this table and insert into a destination table. The desired output for the destination table is:
Index_1
Index_2
Index_3
2
4
5
2
9
2
The logic behind this is numbers in odd positions are indexes (columns), and numbers in even positions are values:
1) "122435" -> "12", "24", "35" -> "Index_1 = 2", "Index_2 = 4", "Index_3 = 5"
2) "2912" -> "29", "12" -> "Index_2 = 9", "Index_1 = 2"
3) "32" -> "Index_3 = 2"
My problem is I don't know if it is possible to use column value as column name in Clickhouse.

How to create a list that shows all unique workers that had service on a week

I am trying to create a query that shows the list of the workers that have at least a shift during the week, but in the query that I created the names of the workers appear multiple times according to the number of shifts they have completed during the period.
WITH time_frame AS
(SELECT date_trunc('week',NOW())-interval '1 week')
select
null as "Employer Ref",
ff.id as "Personnel Ref",
null as "Employment Sequence No",
ff.first_name as Forename,
ff.last_name as Surname,
null as "Second forename",
null as "Third forename ",
case ff.gender
when 'F' then 'Miss'
when 'M' then 'Mr'
else null
end as Title,
null as "Known as",
ff.address1 as "Address line 1",
ff.address2 as "Address line 2",
ff.city as "Address line 3",
null as "Address line 4",
null as "Address line 5",
lp.postcode as Postcode,
'UK' as Country,
null as "Telephone number",
ff.gender as gender,
ff.birth_date as "Date of birth",
ff.mobile as "Mobile Telephone",
au.email as "Email Address",
ff.sort_code as "Bank1 sort code",
ff.account_number as "Bank1 account number",
concat(ff.first_name,' ',ff.last_name) as "Bank1 account name"
from booking_booking bb
join freelancer_freelancer ff on bb.freelancer_id = ff.id
join job_jobrequest jj on bb.jobrequest_id = jj.id
join auth_user au on au.id = ff.user_id
join location_postcode lp on lp.id = jj.postcode_id
WHERE bb.status != 'FC'
AND bb.status != 'BC'
AND bb.status != 'BU'
AND jj.agency_id IN('1')
AND date_trunc('week',jj.date) =
(SELECT *
FROM time_frame)

Filling up an ms-access table with sql

I am very new to databases and I'm currently working with Microsoft Access 2013. The situation is that I have a huge amount of data which I wanna fill in in an already created table (Inventory) by using an SQL-statement in a query.
What I have is the following:
INSERT INTO Inventory (Col 1, Col 2, Col 3, Col 4)
VALUES ("Val 1", "Val 2", "Val 3", "Val 4"),
("Val 5", "Val 6", "Val 7", "Val 8"),
....
("Val 9", "Val 10", "Val 11", "Val 12");
And what I want is simply this table:
Col 1 | Col 2 | Col 3 | Col 4
| | |
Val 1 | Val 2 | Val 3 | Val 4
Val 5 | Val 6 | Val 7 | Val 8
Val 9 | Val 10 | Val 11 | Val 12
The problem is, that I keep getting the error Missing semicolon at the end of sql-statement. Therefore I suppose that I should add a semicolon after each line. If I do this tho, I get the error that access found characters after the semicolon.
What is the right syntax to achieve my multiple-lined INSERT INTO-Statement?
I think MS Access only allows you to insert one record at a time using INSERT . . . VALUES:
INSERT INTO Inventory (Col 1, Col 2, Col 3, Col 4)
VALUES ("Val 1", "Val 2", "Val 3", "Val 4");
INSERT INTO Inventory (Col 1, Col 2, Col 3, Col 4)
VALUES ("Val 5", "Val 6", "Val 7", "Val 8");
....
INSERT INTO Inventory (Col 1, Col 2, Col 3, Col 4)
VALUES ("Val 9", "Val 10", "Val 11", "Val 12");
You can bulk insert using INSERT INTO ... SELECT and a union query:
INSERT INTO Inventory (Col 1, Col 2, Col 3, Col 4)
SELECT "Val 1", "Val 2", "Val 3", "Val 4"
FROM (SELECT First(ID) FROM MSysObjects) dummy
UNION ALL
SELECT "Val 5", "Val 6", "Val 7", "Val 8"
FROM (SELECT First(ID) FROM MSysObjects) dummy
UNION ALL
SELECT "Val 9", "Val 10", "Val 11", "Val 12"
FROM (SELECT First(ID) FROM MSysObjects) dummy
However, the overhead might not make this construct worthwhile, and Access does have a maximum length on single queries of ~65K characters.
To serialize and deserialize tables, I recommend using ADO and persistence. This can properly store field properties, serializing to different file formats or database formats will cause information loss.

Using LAG and comparing the column

I am joining two tables together using a lag function so that the first table will display no duplicate metric rows.
I am however having trouble referencing the lagged column when pre selecting for a join.
My query is as follows, the mentioned column is marked with !!!
select "Campaign",
"Ad group" ,
"Final URL" ,
"Headline 1" ,
"Headline 2" ,
"Description" ,
"Path 1" ,
"Path 2" ,
"Status" ,
"Labels" ,
case when prev_key is null or prev_key != "Key" then "Clicks" end as
"Clicks",
case when prev_key is null or prev_key != "Key" then "Impressions" end
as
"Impressions",
case when prev_key is null or prev_key != "Key" then "Cost" end as
"Cost",
case when prev_key is null or prev_key != "Key" then "Avg. position" end
as
"Avg. position",
case when prev_key is null or prev_key != "Key" then "Initial Leads" end
as
"Initial Leads",
case when prev_key is null or prev_key != "Key" then "Evaluations" end
as
"Evaluations",
case when prev_key is null or prev_key != "Key" then "Won Leads" end as
"Won Leads",
case when prev_key is null or prev_key != "Key" then "Opportunities" end
as
"Opportunities",
"Language",
"Network",
"Main Keyword",
"Cluster Keyword 1",
"Match Type"
from
(SELECT
"x"."Campaign",
"x"."Ad group",
"x"."Final URL",
"x"."Headline 1",
"x"."Headline 2",
"x"."Description",
"x"."Path 1",
"x"."Path 2",
"x"."Status",
"x"."Labels",
!!!lag ("x"."Key") over () AS prev_Key!!!,
"x"."Clicks",
"x"."Impressions",
"x"."Cost",
"x"."Avg. position",
"x"."Initial Leads",
"x"."Evaluations",
"x"."Won Leads",
"x"."Opportunities",
"x"."Language",
"x"."Network",
"x"."Main Keyword",
"x"."Cluster Keyword 1",
"x"."Match Type"
FROM ad_copies_final_joined_concatenated x join
ad_copies_final_to_join_concatenated
using ("Key")
order by "Campaign" desc, "Key"
) sub ;
The output error message is as follows;
ERROR: column "Key" does not exist
LINE 11: case when prev_key is null or prev_key != "Key" then "Cli...
^
You shouldn't use the same syntax for string, and column names.
I suspect the error is due to the use of double quotations with strings.
Try changing everything that is not a column to a single quote mark .
E.G.
case when prev_key is null or prev_key != 'Key' then "Avg. position" end
as "Avg. position"
Or, you actually want to compare prev_key column with Key column. In this case, you forgot to select Key in your inner query, so add it to the select list.

MS Access SQL IIF if false then return old value

I have a question I am doing an Update query and using the IIF function in the process:
Update someTable as tab Set tab.[field1] = "new filed1 value", tab.[field2] = IIF
(
tab[field2] = "some value" , "New value",IIF
(
tab.[field2] = tab.[field2],tab.[field2]))
)) Where tab.[field1] = "Old field 1 value"
With the above query I wanto to change field2 to "New Value" if it equals to "some value" but if it doesn't then I don't want to change it (or put the same value as it was like the above)
So my question is would the below line in the above query work as expected?
IIF
(
tab.[field2] = tab.[field2],tab.[field2]
)
I think the expression is too complicated. This is what you want:
Update someTable as tab
Set tab.[field1] = "new filed1 value",
tab.[field2] = IIF(tab.[field2] = "some value", tab.[field2])
Where tab.[field1] = "Old field 1 value";