I am relatively new to SQL, and I'm probably overlooking a simple answer.
For example, I have a table with the following columns
CustomerID
Hair_Color
Eye_Color
Skin_Color
Braces (Y/N)
I want 4 counts of unique CustomerIDs
I want a count of those that are blonde
Then I want a count of all those that have blue eyes, but if they were blonde, I don’t want them included
Then I want a count of all those that are Caucasian, but if they were blonde or had blue eyes, I don’t want them included
Then I want a count of all those with braces, but if they were blonde, had blue eyes, or were Caucasian, I don’t want them included.
CASE Statements to the rescue:
SELECT
SUM(CASE when hair_color = 'blonde' then 1 ELSE 0 END) as blondes,
SUM(CASE WHEN eye_color = 'blue' and hair_color <> 'blonde' THEN 1 ELSE 0 END) as 'Blue_eyed_non_blondes',
etc..
FROM table
Related
I have a record that contains stat for a certain cricket player.
It has columns having dates, oppositions, Runs, Balls, Dismissals, Match_Number.
I want to do a query (SQL SERVER) to find out the batting average where every runs (Sum) is to be added; innings having a count of all innings except DNB but dismissal should not have a count of "Not Out", "Retired Hurt", "DNB" grouped by the opposition.
Note : DNB means Did not Bat.
The query doesn't have the required number of innings to calculate the average
So the problem is can't gather information for a single entity (count of no. of innings) having two set of parameters.
Without DNB
Without DNB, Not Out, Retired Hurt.
Please suggest.
You can put a case expression within an aggregate to exclude certain rows from a count/sum/average etc. So you could use something like this:
SELECT a.Opposition,
Matches = COUNT(*),
Innings = COUNT(CASE WHEN a.Dismissal <> 'DNB' THEN 1 END),
Runs = SUM(a.Runs),
Average = SUM(a.Runs) / NULLIF(COUNT(CASE WHEN a.Dismissal NOT IN ('DNB', 'Not Out', 'Retired not out') THEN 1 END), 0)
FROM dbo.SRTundlkarODI AS a
GROUP BY a.Opposition;
N.B. I have wrapped the COUNT for the average in NULLIF(<exp>, 0) so that should the batsmen have never got out you avoid a divide by zero error.
I have a table which comprises of 30 columns, all adjacent to one another. Of these 5 are text fields indicating certain details pertaining to that entry and 25 are value fields. Value fields have the column name as Val00, Val01, Val02 .....upto Val24
Based on a logic appearing elsewhere, these value fields input a value for n amount of columns and then drop to 0 for all of the subsequent fields
e.g.
When n is 5 the output will be
Val00
Val01
Val02
Val03
Val04
Val05
Val06
Val07
Val24
1.5
1.5
1.5
1.5
1.5
0
0
0
0
As can be seen, all values starting from val05 will drop to 0 and all columns from Val 05 to Val24 will be 0.
Given this output, I want to find what this n value is and create a new column ValCount to store this value in it.
In Excel this would be fairly straight forward to achieve with the below formula
=COUNTIF(Val00:Val24,">0")
However I'm not sure how we would go about in terms of SQL. I understand that the count function works on a columnar level and not on a row level.
I found a solution which is rather long but it should do the job so I hope it helps you.
SELECT SUM(SUM(CASE WHEN Val00 >= 1 THEN 1 ELSE 0 END)
+ SUM(CASE WHEN Val01 >= 1 THEN 1 ELSE 0 END)
+ SUM(CASE WHEN Val02 >= 1 THEN 1 ELSE 0 END)) As ValCount
I need help with a SQL query to check if a numeric column contains a number in ascending or descending order.
eg. 123456 or 654321
This is to avoid people entering some random values in a customer phone number column, users are required to give valid phone number input.
I want to achieve this without using a function.
UPDATE: #LukStorms had kindly answered my question. Many thanks. Thanks to others who looked at my question and left comments. However I would really appreciate if the comment helps solve the problem. My scenario is different, I cannot post the entire use case here. The ask is I must validate the column in the same way.
To check if it's like a sequence of digits?
Then you can simply use LIKE
select num
, cast(case
when '1234567890123456789' like concat('%',num,'%')
then 1
when '9876543210987654321' like concat('%',num,'%')
then 1
else 0 end as bit) as isSequence
from (values
(123456),
(765432),
(797204)
) nums(num)
num
isSequence
123456
True
765432
True
797204
False
Or use CHARINDEX
select num
, cast(case
when 0 < charindex(concat(num,''),'1234567890123456789') then 1
when 0 < charindex(concat(num,''),'9876543210987654321') then 1
else 0 end as bit) as isSequence
from (values
(123456),
(765432),
(797204)
) nums(num)
Demo on db<>fiddle here
I have a Google sheet with customers that came from different sources and bought different products. Table looks like this:
utm_campaign user_product
campaign_1 1st_product
campaign_2 2nd_product
campaign_3 1st_product
campaign_1 2nd_product
campaign_2 1st_product
I want to count the number of cells in a row "user_product" with different values. what formula I should use to transform it in Data Studio into this:
utm_campaign 1st_product 2nd_product
campaign_1 1 1
campaign_2 1 1
campaign_3 1 0
I have tried this formula
SUM(
CASE
WHEN user_product = "1st_product"
THEN "1"
ELSE "0"
END
)
but something went wrong
Field name contains invalid table alias: t0._339410717_
Seems right except you are casting the numbers as strings by using speech marks so it can't add them up
SUM(
CASE
WHEN user_product = "1st_product"
THEN 1
ELSE 0
END
)
Alternatively you could put the two dimensions into a pivot table with a count to get your required answer
I have a query that I have had make do over the last few years which heavily leans on the users entering in data in a somewhat correct order (i know, first mistake).
The idea is that the users enter a item with the category of CRT in the first 7 lines...and only one. Some times there may be others with this category, but i only want the first one. Now, users sometimes enter the item in after the first 7 rows...leading to another problem. Here is my original query:
Select distinct
d.Job_Number as Rig,
case d.Customer_Name
when 'case' then 'diff case'
else '******'
end as Parent_Customer,
d.Customer_Name,
case d.Reference_Location2
when 'case' then 'diff case'
else '******'
end as Size,
case d.Office_code
when 'case' then 'diff case'
else '****'
end as Office,
d.Rental_Ticket,
case d.job_type
when 'case' then 'diff case'
else '0'
end as Billable,
d.Reference_Location5 as TT
from HP_View_DEL_Ticket_Header_Master as d
left join CSView_INVC_Header_Master as i --left join to report jobs that have not been invoiced
on d.Rental_Ticket = i.Rental_Ticket_or_Tag_Number
join CSView_DEL_Ticket_Lines_Master as l
on d.Rental_Ticket = l.Rental_Ticket
where (d.Ticket_Month between 7 and 7 and d.Ticket_Year = 2017)-- or (d.Ticket_Month between 12 and 12 and d.Ticket_Year = 2016))
and d.Rental_Ticket not in (select dticket from deltick_void)
and d.Ticket_Type = 'D'
and d.Posted_Flag = -1
and l.Row_Counter between 1 and 7 --Currently how I get the correct record, problem is its sometimes not entered in the first 7 rows.
and l.Category_Code = 'CRT'
order by Parent_Customer
I am needing one Ticket number, to one CRT item (the CRT first item). I've tried doing something in the where clause to find the top CRT items but didn't work the way i figured it would.
Any help would be great.
Thanks
BD
EDIT:
Expected OUTPUT
Rig Parent_Customer Customer_Name Size Office Rental_Ticket Billable TT
RIG 642 A A 5 to 5.5 City 12627 0 YES
RIG 525 B B 5 1/2 City 2 12628 0 YES
RIG 603 C C 9 5/8 City 3 12634 0 NO
Incorrect OUTPUT:
Rig Parent_Customer Customer_Name Size Office Rental_Ticket Billable TT
RIG 642 A A 5 to 5.5 City 12627 0 YES
RIG 642 A A 5 to 5.5 City 12627 0 YES
Because the query finds more than one 'CRT' on the Rental Ticket, it returns two records that are the same for the columns I have selected. I am wanting to use ONLY the first one it finds.