Mysql select totals and names - mysql

List the customer first name, last name, and total amount spent (Note: the amount spent is the order subtotal + the tax + the cost to ship from the tblorder table).
i have this code(but the values all come out the same:
Select CONCAT(firstname, ' ' ,lastname) as name, sum(ordersubtotal + ordertax + ordershipcost) as AmountSpent
From tblorder,tblcust
group by name

This should do it:
Select CONCAT(firstname, ' ' ,lastname) as name, sum(ordersubtotal + ordertax + ordershipcost) as AmountSpent
From tblorder a
inner join tblcust b ON a.custId=b.custId
group by name;
YOu did not define on what you are joining the tables.
In your code style that would be:
Select CONCAT(firstname, ' ' ,lastname) as name, sum(ordersubtotal + ordertax + ordershipcost) as AmountSpent
From tblorder a,tblcust b
where a.custId=b.custId
group by name;
(Both should give the same result)

Related

Query multiple records from table using derived field

I'm working on a legacy database system which deals with property reports and I am attempting to update a query which shows multiple reports within a time period for the same address. I am using MySQL Workbench to run this query.
The table has a UPRN field for unique addresses, which is fine, however addresses can be manually added without a UPRN. The table also has address1, address2, address3, town, postcode fields. There is NO field which contains the whole address as one line.
We already have a query which uses the UPRN field to generate a list of multiple records within a timescale; however, this will obviously exclude multiple reports without a UPRN.
SELECT * FROM
`rep_base_report` `rep`
WHERE
`rep`.`UPRN` IN (SELECT
`rep2`.`UPRN` AS `UPRN`
FROM
`rep_base_report` `rep2`
WHERE
`rep2`.`STATUS` = 'LODGED'
AND `rep2`.`GENERATED_DATE` > (CURDATE() - INTERVAL 3 MONTH)
GROUP BY `rep2`.`UPRN`
HAVING (COUNT(0) > 1)
ORDER BY `rep2`.`GENERATED_DATE` DESC)
GROUP BY `rep`.`RepReference`
ORDER BY `rep`.`UPRN`
In my head, if I could CONCAT address1, address2 and postcode and use this as the basis for the check, it would give the appropriate output, but I've no idea how to accomplish this.
I've attempted the following but it's giving fewer values that I was expect (I've manually checked some sample data in Excel to see what I should be expecting).
SELECT *
FROM `rep_base_report` `rep`
WHERE
#property :=CONCAT(`rep`.`ADDRESS1`, ' ' ,`rep`.`ADDRESS2`, ' ' ,`rep`.`POSTCODE`) IN (
SELECT #property2 :=CONCAT(`rep2`.`ADDRESS1`, ' ' ,`rep2`.`ADDRESS2`, ' ' ,`rep2`.`POSTCODE`) AS `PROPERTY`
FROM `rep_base_report` `rep2`
WHERE `rep2`.`STATUS` = 'LODGED'
AND `rep2`.`GENERATED_DATE` > CURDATE() - INTERVAL 3 MONTH
GROUP BY #property2
HAVING COUNT(0) > 1
ORDER BY `rep2`.`GENERATED_DATE` DESC
)
GROUP BY `rep`.`RepReference`
ORDER BY `rep`.`UPRN`
SELECT *
FROM `rep_base_report` `rep`
WHERE
CONCAT(`rep`.`ADDRESS1`, ' ', `rep`.`ADDRESS2`, ' ', `rep`.`POSTCODE`) IN (
SELECT CONCAT(`rep2`.`ADDRESS1`, ' ', `rep2`.`ADDRESS2`, ' ', `rep2`.`POSTCODE`) AS `PROPERTY`
FROM `rep_base_report` `rep2`
WHERE `rep2`.`STATUS` = 'LODGED'
AND `rep2`.`GENERATED_DATE` > CURDATE() - INTERVAL 3 MONTH
GROUP BY CONCAT(`rep2`.`ADDRESS1`, ' ', `rep2`.`ADDRESS2`, ' ', `rep2`.`POSTCODE`)
HAVING COUNT(0) > 1
ORDER BY `rep2`.`GENERATED_DATE` DESC
)
GROUP BY `rep`.`RepReference`
ORDER BY `rep`.`UPRN`

How to display a $ next to a number in MYSQL

this is what I am trying, but the '$' doesn't get displayed in the result set
SELECT
id,
CONCAT(first_name, ' ', last_name),
CONCAT('$' + '' + salary),
started_on
FROM employees
WHERE salary >= 100000 AND started_on >= '20180101'
ORDER BY salary DESC, id;
if you want to do it in SQL:
CONCAT('$', salary)
You really should do it in the presentation layer (your app).

SQL Compound query if-else or Case Statement

I have a table with Customer_ID, Customer_Name, Address1, Address2, Mail_Address1, Mail_Address2, etc etc.
In some cases, Mail_Address1 = 'Same' or ''.... which basically means that I need to extract Address1 + Address2 otherwise ignore and take Mail_Address1 + Mail_Address2.
My pseudo SQL Query looks like:-
// The query that would give me all the records with the same address as Address1 for Mailing Address //
SELECT Customer_ID, Customer_Name, Address1 + ', ' + Address2 as Address, ....
FROM Customers
Where Customer_ID != 0 AND (Mail_Address1 ='Same' or Mail_Address1 ='')
AND
SELECT Customer_ID, Customer_Name, Mail_Address1 + ', ' + Mail_Address2 as Address, ....
FROM Customers
Where Customer_ID != 0 AND Mail_Address1 !='Same' AND Mail_Address1 !=''
How do I combine these two queries so that I can have one query which would choose the correct address depending on the condition. (Same or empty string).
Have you considered a CASE statement?
SELECT
CASE
WHEN Customer_ID != 0 AND (Mail_Address1 ='Same' OR Mail_Address1 = '')
THEN Address1 + ', ' + Address2
ELSE Mail_Address1 + ', ' + Mail_Address2
END AS address
FROM Customers

My SQL - Refer data from another table rows

I have no idea whether it is possible or not.
I have two tables:
Columns in hospitals Table
hospitalID
Name
AverageRating
Columns in ratings Table
ID
rating1
rating2
rating3
rating4
rating5
rating6
hospitalID
rating1 to rating6 is types of ratings. Now By calculation I am able to get average rating of particular hospital in ratings table from following SELECT Query
SELECT IFNULL((SUM(charges) + SUM(behaviour) + SUM(admission) + SUM(properInformation)
+ SUM(hygine) + SUM(treatment))/(count(hospitalID) * 6), 0
) AverageRating,COUNT(ID) RatingCount
FROM ratings
WHERE hospitalID = '111111'
Above query works for me perfectly but this averageRating I also want to calculate in my hospitals table because I want to ranks hospitals.
Is there any functions in mySQL through which I can calculate average rating to hospitals table by referring ratings table.
Rating Table
Query Output Table
Based on the given table structure, you can try this.
EDIT
SELECT avgratings.*, #curRow := #curRow + 1 AS hospitalRank
FROM (
SELECT (SUM(r.`rating1`)+SUM(r.`rating2`)+SUM(r.`rating3`)+SUM(r.`rating4`)+SUM(r.`rating5`)+SUM(r.`rating6`))/(COUNT(r.`hospitalID`)*6) AS AverageRating, h.hospitalID
FROM hospitals h INNER JOIN ratings r
ON h.`hospitalID`=r.`hospitalID`
WHERE 1 GROUP BY r.`hospitalID`
) avgratings JOIN (SELECT #curRow := 0) rank
ORDER BY avgratings.AverageRating DESC
2nd Query to get rank of a particular hospital.
SELECT tablea.*
FROM (
SELECT avgratings.*, #curRow := #curRow + 1 AS hospitalRank
FROM (
SELECT (SUM(r.`rating1`)+SUM(r.`rating2`)+SUM(r.`rating3`)+SUM(r.`rating4`)+SUM(r.`rating5`)+SUM(r.`rating6`))/(COUNT(r.`hospitalID`)*6) AS AverageRating, h.hospitalID
FROM hospitals h INNER JOIN ratings r
ON h.`hospitalID`=r.`hospitalID`
WHERE 1 GROUP BY r.`hospitalID`
) avgratings JOIN (SELECT #curRow := 0) rank
) tablea
WHERE tablea.hospitalID=1 ORDER BY tablea.AverageRating DESC
Replace 1 in WHERE block with hospitalID.
I am not sure I understand your question...
You get the avarage of a single record with:
charges + behaviour + admission + properInformation + hygine + treatment / 6
You get the total avarage hence with:
avg(charges + behaviour + admission + properInformation + hygine + treatment / 6)
I order to get it per hospital, you'd group by hospital_id:
select
hospitalid,
avg(charges + behaviour + admission + properinformation + hygine + treatment / 6) as avr,
count(*) as rating_count
from ratings
group by hospitalid
order by 2 desc;
You can select the hospital data (e.g. the hospital name) along by joining the hospital table. E.g.
select
h.hospitalid,
h.name,
avg(r.charges + r.behaviour + r.admission +
r.properinformation + r.hygine + r.treatment / 6) as average_rating,
count(*) as rating_count
from hospitals h
left join ratings r on r.hospitalid = h.hospitalid
group by h.hospitalid
order by average_rating desc;

SQL Query to display unique records based on certain conditions

[I have gone through a large number of questions before posting this question.]
I have a table which contains 4 fields. It is ClientId, ClientName,ClientAddress, ClientCity.
Now, I have an autocomplete textbox control where I need to fetch & display client name.
The problem is that in our database we have same client from the same city from different address.
Now the requirement given to me is that the user should be able to see "ClientName" or "ClientName + ClientCity" or "ClientName+ClientCity+ClientAddress" to make it easy for user to select the client.
It means that I need to add a column to the query till it makes it unique.
I am sure there must be some simple solution to this which I am not getting for past 2 days now.
As shown in below sample data, If I show only "D" as a client name to the end user, he will be confused as in which client "D" he has to select. So we need to concatenate city and address to make it unique.
I am expecting an output as below.
You can use COUNT() OVER() for this:
;WITH CTE AS(
SELECT *,
ByName = COUNT(*) OVER(PARTITION BY ClientName),
ByCity = COUNT(*) OVER(PARTITION BY ClientName,ClientCity)
FROM Client
)
SELECT
CASE
WHEN ByName = 1 AND ByCity = 1 THEN ClientName
WHEN ByName > 1 AND ByCity = 1 THEN ClientName + ', ' + ClientCity
WHEN ByName > 1 AND ByCity > 1 THEN ClientName + ', ' + ClientCity + ', ' + ClientAddress
END
FROM CTE
ORDER BY ClientID
RESULT
Client
--------------------------------------------------------
A
B
C, New York
D, London, LSE Houghton Streen London WC2A 2AE
D, London, Hard Rock Cafe London 150 Old Park Lane
F
C, Paris
See SQL Fiddle.
If you are using SQL Server, you can try the string concatenation using "+" operator as follows
select
ClientName + ', ' + ClientCity + ', ' + ClientAddress as ClientData,
Concat(ClientName, ', ', ClientCity, ', ', ClientAddress) Client
from client
The second concatenation is built using SQL CONCAT() funtion will work on SQL Server 2012 and later
For the conditional data following SELECT statement can help,
select
-- ClientName + ', ' + ClientCity + ', ' + ClientAddress as ClientData,
-- Concat(ClientName, ', ', ClientCity, ', ', ClientAddress) ClientDtata2,
client =
case when count(*) over (partition by ClientName) = 1 then ClientName
else
case when count(*) over (partition by ClientName, ClientCity) = 1 then CONCAT(ClientName, ', ' , ClientCity)
else Concat(ClientName, ', ', ClientCity, ', ', ClientAddress)
end
end
from client
TRY THIS,
Declare #t table (clientid int identity(1,1),clientname varchar(50),clientCITY varchar(50)
,clientaddress varchar(200))
insert into #t values ('A','PARIS','DFSDFSDF'), ('C','NEW YORK','DFSDFSDF')
,('C','PARIS','WEQWEQWE'),('D','LONDON','QWE342'),('D','LONDON','21DXCXZC')
;With CTE as
(select *,ROW_NUMBER()over(partition by clientname order by clientid)rn
,ROW_NUMBER()over(partition by clientname,ClientCity order by clientid)rn1
from #T A
)
--select * from cte
select clientname+','+ clientCITY
from cte A WHERE
EXISTS(SELECT CLIENTID FROM CTE WHERE clientname=A.clientname AND RN>1 AND RN1<=1)
UNION ALL
select clientname+','+ clientaddress
from cte A WHERE
EXISTS(SELECT CLIENTID FROM CTE WHERE clientname=A.clientname AND RN1>1)
UNION ALL
select clientname
from cte A WHERE not
EXISTS (SELECT CLIENTID FROM CTE WHERE clientname=A.clientname AND RN>1 )