Why does my SQL syntax show null? - sql

I am little perplexed on why my result of this statement shows null in the Project_ID. I took a look at the below post and tried the inner join instead but the result was futile, the same as with the left join. I have only two distinct Project_ID. For some odd reason, the Name is being stated again with the Count added from the previous listings. Why is it doing this and how can I fix this? Please provide your advice.
Why does my SQL query return rows with NULL? It should never return rows with NULL
select dp."Name",count(dp."Name") Count,max(to_char(ft."Hours",'9,999')) "Maximum Hours Worked",
max(ft."Salary"::money) "Maximum Salary",
ft."Project_ID"
from facttable ft
left join alldatainput dp on dp."alldatainputpk" = ft."alldatainputfk"
group by rollup(dp."Name",ft."Project_ID")
Result:
Name Count Maximum Hours Worked Maximum Salary Project_ID
Hulk Hogan 157 3,500 $432,995.00 LFC
Hulk Hogan 43 3,499 $550,000.00 PCR
Hulk Hogan 200 3,500 $550,000.00 (null)
Andre the Giant 42 5,300 $870,000.00 PCR
Andre the Giant 42 5,300 $870,000.00 (null)
Bret Hart 5 3,675 $512,000.00 LFC
Bret Hart 10 4,193 $716,510.00 PCR
Bret Hart 15 4,193 $716,510.00 (null)
Winnie the Pooh 561 5,600 $929,654.00 PCR
Winnie the Pooh 561 5,600 $929,654.00 (null)
1000 5,600 $929,654.00 (null)

Grouping Sets
select
dp.Name,count(dp."Name") Count,
max(to_char(ft."Hours",'9,999')) "Maximum Hours Worked",
max(ft."Salary"::money) "Maximum Salary",
ft."Project_ID"
from
facttable ft
left join
alldatainput dp on dp."alldatainputpk" = ft."alldatainputfk"
group by grouping sets ((dp."Name",ft."Project_ID"), ())

Related

Get max of sum during joining two tables

I want to get the subscriber that has maximum value of Bill (Total Bill).
I tried using the following script but SQL did not execute successflly.
Please help me on what I did wrong on this.
I have 2 tables:
Subscriber
FirstName
MIN
Ben
258999542
Reed
458524896
Steve
586692155
Clint
1007772121
Frank
1287548752
Jane
2345824215
Total Bill
Total
MIN
131.5
258999542
139.4
458524896
164
586692155
101
1007772121
224.12
1287548752
97.52
2345824215
And here's the code I tried:
SELECT MAX(B.Total), S.FirstName
FROM Subscriber AS S
JOIN Bill AS B ON S.MIN = B.MIN
It seems you just need TOP + ORDER BY:
SELECT TOP 1 B.Total, S.FirstName
FROM Subscriber AS S
JOIN Bill AS B ON S.MIN = B.MIN
ORDER BY B.Total DESC;
That's based on the fact that your sample data isn't showing multiple Bill records per Subscriber therefore you don't need a sum.

How to fetch the summation of three columns from three tables in SQL?

whenever I am fetching the sum from one single table, the output is correct. But whenever I combine three/two separate table at that time the output becomes wrong.
my SQL for a single table is:
select users.name, SUM(BC.individual_cost) as breakfast_cost
from breakfast_orders BO, breakfast_costs BC,users
WHERE (BO.date=BC.date) and (BO.user_id=users.id)
GROUP BY(BO.user_id)
and here the output is:
name breakfast_cost
Munna Khandakar 300
Afifa Marowa Anha 180
Fouzia Kabir 50
Atiya Anam Afra Riya 50
in the same way, there are also 2 tables which gives a particular result which is correct. But when ever I join them, the overall result changes.
when I join them like this:
select users.name, SUM(BC.individual_cost) as breakfast_cost, SUM(LC.individual_cost) as lunch_cost, SUM(DC.individual_cost) as dinner_cost
from breakfast_orders BO, breakfast_costs BC,users, lunch_orders LO, lunch_costs LC, dinner_orders DOr, dinner_costs DC
WHERE (BO.date=BC.date) and (BO.user_id=users.id) AND (LO.date=LC.date) AND (LO.user_id=users.id) AND (DOr.date=DC.date) AND (DOr.user_id=users.id)
GROUP BY(users.id)
then the result becomes
name breakfast_cost lunch_cost dinner _cost
Munna Khandakar 2700 3222 4878
Afifa Marowa Anha 720 552 968
Fouzia Kabir 100 76 242
Atiya Anam Afra Riya 100 76 242
here, only by observing the breakfast_cost we can say that the query in not OK. SO if any one help me then I will be very grateful to him.
TIA
As #jarlh suggests better to use the explicit joins.
Try the Following
select u.name,
SUM(BC.individual_cost) as breakfast_cost,
SUM(LC.individual_cost) as lunch_cost,
SUM(DC.individual_cost) as dinner_cost
from users u
Left Join breakfast_orders BO on BO.user_id=u.id
Left Join breakfast_costs BC on BO.date=BC.date
Left Join lunch_orders LO on LO.user_id=u.id
Left Join lunch_costs LC on LO.date=LC.date
Left Join dinner_orders DO on DO.user_id=u.id
Left Join dinner_costs DC on DO.date=DC.date
Where not (BO.user_id is null and LO.user_id is null and DO.user_id is null)

Create column based on grouping other values

I have difficulties formulating my issue.
I have a view which brings these results. There's a need to add a column to the view, which will pair up round-trip flights with identical number.
Flt_No From_Airport To_Airport Dep_Date RequiredResult
124 |LCA |CDG |10/19/14 5:00 1
125 |CDG |LCA |10/19/14 10:00 1
197 |LCA |BCN |10/4/12 5:00 2
198 |BCN |LCA |10/4/12 11:00 2
501 |LCA |HER |15/8/12 12:05 3
502 |HER |LCA |15/8/12 15:15 3
I.e. flight 124 is going from Larnaca to CDG, and flight 125 is going back from CDG to Larnaca - they both have to have the same identifier.
Round-trip flights will always have following flight numbers.
I have a bunch of conditions which I won't write now.
Omitting hours is not an option, they're important.
I was thinking dense_rank() but I don't know how to create one identifier for 2 flights with different numbers, please help.
If your data is similar to the sample data posted, then the following query should give the required result:
SELECT *,
DENSE_RANK() OVER (ORDER BY CASE
WHEN From_Airport < To_Airport THEN From_Airport
ELSE To_Airport
END)
FROM mytable
Join conditions are not limited to simple equality. Assuming {Flight No, Departure, Destination} is unique on any one day, then a self join should do it:
select whatever
from flights outbound
inner join flights inbound on outbound.flt_no+1 = inbound.flt_no
and cast(outbound.dep_date, date)
= cast(inbound.dep_date, date)
and outbound.From_Airport = inbound.To_Airport
and outbound.To_Airpott = inbound.From_Ariport

Ms Access SQL calculation from multiple rows

I have the following query:
SELECT
InspectionID, Distance, Continuous, structural_grade
FROM
Conditions
WHERE
Continuous LIKE ("S%") OR Continuous LIKE ("F%")
ORDER BY
InspectionId ASC, Distance ASC
Which outputs:
262 60.80 S01 3
262 73.10 F01 3
262 82.60 S02 2
262 140.30 F02 2
263 30.80 S01 2
263 46.60 F01 2
380 4.60 S01 3
380 8.50 F01 3
380 9.80 S02 4
380 28.20 F02 4
380 77.70 S03 4
380 97.70 F03 4
The ordering is correct. However I'm stuck at what to do next.
Each "S" has a matching "F" with the same numbers Ex S01, F01. I need to access the Distance field of each "F" and minus "S" distance from it.
For examples F01 has a distance of 73.10 and S01 60.80 so the distance between is 12.3. I need to do this for each records and them numbers after the "S" and "F" can go really high yet will always match. ex. S999 - F999
Use the Mid() function to extract the digits from your Continuous field: Mid("S01", 2) yields "01". Then use those digits when you join the F and S rows.
With your sample data in Access 2010, the following query gave me this result set:
SELECT
f.InspectionID,
f.Continuous,
s.Continuous,
f.Distance AS F_distance,
s.Distance AS S_distance,
f.Distance - s.Distance AS F_minus_S
FROM
Conditions AS f
INNER JOIN
(
SELECT
InspectionID,
Continuous,
Distance,
Mid([Continuous],2) AS digits_only
FROM Conditions
WHERE Continuous ALike 'S%'
) AS s
ON
f.InspectionID = s.InspectionID
AND Mid(f.[Continuous],2) = s.digits_only
WHERE f.Continuous ALike 'F%'
ORDER BY f.InspectionId ASC, f.Distance ASC;
I included several columns which I doubt you want in your final query. But I think they can be useful during development and testing.
Beware the Access query designer will complain it can't represent that join condition in Design View. If you set up the join in SQL View, you can then run the query without Access complaining.
SELECT a.continuous AS 'S Continuous',
a.distance AS 'S Distance',
b.continuous AS 'F Continuous',
b.distance AS 'F Distance',
abs(a.distance - b.distance) AS 'Difference'
FROM Conditions a
INNER JOIN Conditions b
ON a.InspectionID = b.InspectionID
AND substring(a.continuous,2,len(a.continuous)-1) = substring(b.continuous,2,len(b.continuous)-1)
WHERE a.Continuous LIKE 'S%'
AND b.Continuous LIKE 'F%'
ORDER BY a.InspectionId ASC, a.Distance ASC

Multiple counts in a query

I'm writing a query that counts company complaints. The query should count the total number of complaints from a company and also break it down into who called from the company to make the complaint. So an example output would be:
Company Ref Company Name Company Complaints Caller Caller Complaints
11 Argos 10 Steve 8
11 Argos 10 JIM 2
So as you can see the query counts the total number of complaints, then also breaks it down to who complained. So far I have everything perfect apart from the total count. My code is:
SELECT COMPANYREF,
COMPANY,
(SELECT COUNT(COMPANYREF)
FROM XCALLSTABLE) AS CompanyCalls,
CALLER,
COUNT(*)
FROM XCALLSTABLE
JOIN XCUSTOMERTABLE ON (XCALLSTABLE.COMPANYREF = XCUSTOMERTABLE.CUSTREF)
JOIN XTELEPHONETABLE ON (XCUSTOMERTABLE.TELEPHONE = XTELEPHONETABLE.PHONENUMBER)
GROUP BY COMPANYREF,
COMPANY,
CALLER
HAVING COUNT(*) > 0 ;
Some sample output for the current code is:
Company Ref Company Name Company Complaints Caller Caller Complaints
145 Comfiture Traders 500 Alexis Patel 4
The issue here is the total count for the company just counts every row, whereas I'm trying to count the occurances of that company appearing in the column.
Any and all help would be greatly appreciated.
Using sstan's code gave a result of
111 Medusa Shipping 4 Lily Morgan 5
111 Medusa Shipping 4 Ruby Walker 6
Whereas the result should be
111 Medusa Shipping 11 Lily Morgan 5
111 Medusa Shipping 11 Ruby Walker 6
I'm sure there is a cleaner way of doing this, but the following query should work:
SELECT companyref,
company,
CompanyCalls,
caller,
COUNT(*)
FROM (SELECT c.companyref,
company,
COUNT(*) OVER (PARTITION BY c.companyref) AS CompanyCalls,
caller
FROM xcallstable c
JOIN xcustomertable ct
ON ct.custref = c.companyref
JOIN xtelephonetable t
ON t.phonenumber = ct.telephone)
GROUP BY companyref, company, CompanyCalls, caller
HAVING COUNT(*) > 0