SQL sort data based on different columns - mysql

I need some help with an SQL problem. I'm not sure it's possible to do, but i have this table:
Obtained from this SQL statement:
SELECT distinct Account.Box, Account.Name, Account.Currency, Account.LastUpdated, Account.LastUpdatedBy, Transactions.Totals
FROM Account
LEFT JOIN Transactions
ON Account.AccountGUID = Transactions.AccountGUID
What i would like to end up with is this result:
So basically comparing the Totals for each groups of Name or Currency, to obtain the highest Totals for each group. (NULL values are to be replaced by zeroes).

You seem to just want a group by:
SELECT a.Box, a.Name, a.Currency, a.LastUpdated, a.LastUpdatedBy,
MAX(t.Totals) as Totals
FROM Account a LEFT JOIN
Transactions t
ON a.AccountGUID = t.AccountGUID
GROUP BY a.Box, a.Name, a.Currency, a.LastUpdated, a.LastUpdatedBy;
Note: I also added table aliases to make the query easier to understand.

Try with this following one ,hope you will get the result what you are expecting.
select * from
(SELECT distinct Account.Box, Account.Name, Account.Currency, Account.LastUpdated, Account.LastUpdatedBy, Transactions.Totals as Totals
FROM Account
LEFT JOIN Transactions
ON Account.AccountGUID = Transactions.AccountGUID) as p
where p.Totals = (select max(totals) from transactions)
group by Box, Name, Currency, LastUpdated, LastUpdatedBy ;
(or)
use the following one also
SELECT a.Box, a.Name, a.Currency, a.LastUpdated, a.LastUpdatedBy,
MAX(t.Totals) as Totals
FROM Account a LEFT JOIN
Transactions t
ON a.AccountGUID = t.AccountGUID
GROUP BY a.Box, a.Name, a.Currency, a.LastUpdated, a.LastUpdatedBy;
Thanks.

Related

How to integrate multiples sub querys with a sum and group by's

I need to show the user info and multiple sums with their own "where and group by" qualifiers that refer to the user's balance of transactions.
I need to show the real balance, the bonus balances and the total balance.
It's simple to do it with one sum but I can't do it with multiple sums.
Here's my query with the 'real balance':
SELECT v2_user.id, v2_user.username, v2_user.first_name,
v2_user.last_name, coalesce(SUM(v2_wallet.amount),0) AS 'Real balance'
from v2_wallet
join v2_user
on v2_wallet.user_id = v2_user.id
WHERE TYPE NOT LIKE '%BONUS%'
group by v2_wallet.user_id
I want to add 2 more columns to my query:
SELECT COALESCE(SUM(v2_wallet.amount),0) AS 'bonus balance' from
v2_wallet
WHERE TYPE LIKE '%BONUS%' group by user_id
SELECT COALESCE(SUM(v2_wallet.amount),0) AS 'total balance' from v2_wallet group by user_id
I haven't done MySql in a while. But generally this code should it. This is tested with SQL server sql syntax.
SELECT U.UserID,U.FirstName,T.TOTAL,B.BONUS
FROM Users U
LEFT JOIN (SELECT USERID, COALESCE (SUM(AMOUNT),0) AS TOTAL
FROM WALLET
GROUP BY USERID) AS T ON U.UserID=T.UserId
LEFT JOIN ( SELECT USERID, COALESCE (SUM(AMOUNT),0) AS BONUS
FROM WALLET
WHERE TYPE='BONUS'
GROUP BY USERID) AS B ON U.USERID=B.USERID
Embed the condition inside the SUM instead of the WHERE clause, relying on the fact that booleans evaluate as 0 or 1.
SELECT v2_user.id, v2_user.username, v2_user.first_name, v2_user.last_name,
SUM(v2_wallet.amount*(TYPE not like '%BONUS%')) AS 'Real balance',
SUM(v2_wallet.amount*(TYPE like '%BONUS%')) AS 'Bonus balance',
SUM(v2_wallet.amount) AS 'Total balance'
from v2_wallet
join v2_user
on v2_wallet.user_id = v2_user.id
group by v2_wallet.user_id
If v2_wallet.amount might be NULL, you need to use COALESCE(v2_wallet.amount,0) above.
If you don't like the looks of that, you can use IF instead of multiplication, like
SELECT v2_user.id, v2_user.username, v2_user.first_name, v2_user.last_name,
SUM(IF(TYPE not like '%BONUS%',v2_wallet.amount*,0)) AS 'Real balance',
SUM(IF(TYPE like '%BONUS%', v2_wallet.amount, 0)) AS 'Bonus balance',
SUM(v2_wallet.amount) AS 'Total balance'
from v2_wallet
join v2_user
on v2_wallet.user_id = v2_user.id
group by v2_wallet.user_id

SQL Query - Determine who has only one gift record

I would like to know how I can write a SQL Script so a within a group of individuals initially selected:
SELECT [RECORDS].[CONSTITUENT_ID]
,[RECORDS].[FIRST_NAME]
,[RECORDS].[LAST_NAME]
,[DATEADDED]
,[DTE]
,[Amount]
,[REF]
,[TYPE]
FROM [re7].[dbo].[GIFT]
INNER JOIN [re7].[dbo].[RECORDS]
ON GIFT.CONSTIT_ID LIKE RECORDS.ID
WHERE ([DTE] BETWEEN '2/7/2015' AND '2/8/2015')
ORDER BY [DATEADDED] DESC
select only individuals who are "First Time Donors" (or someone who only has one gift in [re7].[dbo].[GIFT].
[RECORDS] is a table of all the constituents.
[GIFT] is a table of all recorded Gifts.
The output of the above Query, is just a table with:
CONSTITUENT_ID, FIRST_NAME, LAST_NAME, DATEADDED, DTE, Amount, REF, TYPE
I pretty much want to see the same output format, but I would like the query to select only CONSTITUENT_ID who only have 1 GIFT (by their Record ID) in [re7].[dbo].[GIFT].
I apologize for the lack of data to show. I wish I could describe better....
SELECT [RECORDS].[CONSTITUENT_ID]
,[RECORDS].[FIRST_NAME]
,[RECORDS].[LAST_NAME]
,[DATEADDED]
,[DTE]
,[Amount]
,[REF]
,[TYPE]
FROM [re7].[dbo].[GIFT]
INNER JOIN [re7].[dbo].[RECORDS]
ON GIFT.CONSTIT_ID LIKE RECORDS.ID
WHERE ([DTE] BETWEEN '2/7/2015' AND '2/8/2015')
AND GIFT.CONSTIT_ID IN (
SELECT CONSTIT_ID FROM re7.dbo.Gift GROUP BY CONSTIT_ID HAVING COUNT(*) = 1
) /* another option is to add a subquery to the query you already had */
ORDER BY [DATEADDED] DESC
This solution simply selects all the constituents who have made only one donation and then joins to that, thereby limiting the result set.
SELECT
r.[CONSTITUENT_ID]
,r.[FIRST_NAME]
,r.[LAST_NAME]
,[DATEADDED]
,[DTE]
,[Amount]
,[REF]
,[TYPE]
FROM
(select [CONSTIT_ID] from [re7].[dbo].[GIFT] group by [CONSTIT_ID] having count([CONSTIT_ID]) = 1) g1
inner join [re7].[dbo].[GIFT] g
on g.[CONSTIT_ID] = g1.[CONSTIT_ID]
INNER JOIN [re7].[dbo].[RECORDS] r
ON g.CONSTIT_ID LIKE r.RECORDS.ID
WHERE ([DTE] BETWEEN '2/7/2015' AND '2/8/2015')
ORDER BY [DATEADDED] DESC

MySQL Query, multiple counts and sums

I have a MySQL query that outputs to a php table but I'm having issues in joining two tables that both use a COUNT:
$query = "SELECT mqe.registration,
COUNT(*) AS numberofenqs,
COUNT(DISTINCT ucv.ip) AS unique_views,
SUM(ucv.views) AS total_views
FROM main_quick_enquiries AS mqe
LEFT OUTER JOIN used_car_views AS ucv
ON ucv.numberplate = mqe.registration
WHERE mqe.registration IS NOT NULL
GROUP BY mqe.registration ORDER BY numberofenqs DESC";
The query runs, but the number within the numberofenqs column is always wrong as i know from performing that query on its own that it comes in with the correct result:
SELECT registration, COUNT(*) AS numberofenqs FROM main_quick_enquiries GROUP BY registration ORDER BY numberofenqs DESC
Why is the COUNT(*) not working correctly in top query code and where is it getting the figures from?
it could be because of LEFT OUTER JOIN ...
Try to run this:
SELECT registration
, count(*)
FROM main_quick_enquiries
GROUP BY registration
and compare it with this result
SELECT mqe.registration
, count(*)
FROM main_quick_enquiries mqe
LEFT OUTER JOIN used_car_views ucv
ON ucv.numberplate = mqe.registration
GROUP BY mqe.registration
There could be a problem :) in duplicity rows... try to find one specific registration number, and compare the details of both query
SELECT *
FROM main_quick_enquiries
WHERE registration = XXXX
+
SELECT *
FROM main_quick_enquiries mqe
LEFT OUTER JOIN used_car_views ucv
ON ucv.numberplate = mqe.registration
WHERE registration = XXXX
you should see the diffs
Thanks All, but I think I've nailed it with COUNT(DISTINCT mqe.id) instead of COUNT(*).

sql counts wrong number of likes

I have written an sql statement that besides all the other columns should return the number of comments and the number of likes of a certain post. It works perfectly when I don't try to get the number of times it has been shared too. When I try to get the number of time it was shared instead it returns a wrong number of like that seems to be either the number of shares and likes or something like that. Here is the code:
SELECT
[...],
count(CS.commentId) as shares,
count(CL.commentId) as numberOfLikes
FROM
(SELECT *
FROM accountSpecifics
WHERE institutionId= '{$keyword['id']}') `AS`
INNER JOIN
account A ON A.id = `AS`.accountId
INNER JOIN
comment C ON C.accountId = A.id
LEFT JOIN
commentLikes CL ON C.commentId = CL.commentId
LEFT JOIN
commentShares CS ON C.commentId = CS.commentId
GROUP BY
C.time
ORDER BY
year, month, hour, month
Could you also tell me if you think this is an efficient SQL statement or if you would do it differently? thank you!
Do this instead:
SELECT
[...],
(select count(*) from commentLikes CL where C.commentId = CL.commentId) as shares,
(select count(*) from commentShares CS where C.commentId = CS.commentId) as numberOfLikes
FROM
(SELECT *
FROM accountSpecifics
WHERE institutionId= '{$keyword['id']}') `AS`
INNER JOIN account A ON A.id = `AS`.accountId
INNER JOIN comment C ON C.accountId = A.id
GROUP BY C.time
ORDER BY year, month, hour, month
If you use JOINs, you're getting back one result set, and COUNT(any field) simply counts the rows and will always compute the same thing, and in this case the wrong thing. Subqueries are what you need here. Good luck!
EDIT: as posted below, count(distinct something) can also work, but it's making the database do more work than necessary for the answer you want to end up with.
Quick fix:
SELECT
[...],
count(DISTINCT CS.commentId) as shares,
count(DISTINCT CL.commentId) as numberOfLikes
Better approach:
SELECT [...]
, Coalesce(shares.numberOfShares, 0) As numberOfShares
, Coalesce(likes.numberOfLikes , 0) As numberOfLikes
FROM [...]
LEFT
JOIN (
SELECT commentId
, Count(*) As numberOfShares
FROM commentShares
GROUP
BY commentId
) As shares
ON shares.commentId = c.commentId
LEFT
JOIN (
SELECT commentId
, Count(*) As numberOfLikes
FROM commentLikes
GROUP
BY commentId
) As likes
ON likes.commentId = c.commentId

Microsoft Access - How to perform validation check and produce error message

I would like to produce an error message when the (sumofqtyreturn + sumofqtyissued) is greater than sumofqtyordered. I want to carry out this validation check so that when the user enters a value(qtyreturn or qtyissued) which is greater than the balance, the system should produce an error. Can this be done?
This is the sql view for my query:
SELECT i.itemNo, Nz(TotalOrdered,0), Nz(TotalReturned,0), Nz(TotalIssued,0),
(Nz(TotalOrdered,0)-Nz(TotalIssued,0)+Nz(TotalReturned,0)) AS Balance
FROM ((item AS i
LEFT JOIN (SELECT itemno, Sum(qtyordered) AS TotalOrdered
FROM delivered_item
GROUP BY itemno) AS d ON d.itemno=i.itemno)
LEFT JOIN (SELECT itemno, Sum(qtyreturn) AS TotalReturned FROM item_return
GROUP BY itemno) AS r ON r.itemno=i.itemno)
LEFT JOIN (SELECT itemno, Sum(qtyissued) AS TotalIssued FROM item_issued
GROUP BY itemno) AS iss ON iss.itemno=i.itemno
or any1 has other good idea of how to inform/warn the user something is wrong about the qtyissued/qtyreturn?(value too large)
Here is the general idea.
SELECT q.AText,
q.SumOfANumber,
q.SumOfADecimal,
IIf([SumOfANumber]-[SumOfADecimal]<0,"Problem!","Yes") AS IsOkay
FROM (SELECT t.AText,
Sum(t.ANumber) AS SumOfANumber,
Sum(t.ADecimal) AS SumOfADecimal
FROM Table1 As t
GROUP BY t.AText) AS q;
The aggregate query becomes a subquery and the relevant fields are compared in the main query. I have used aliases for Table1, so you have Table1 As t, and for the subquery.