Mysql query output right, count wrong - mysql

SELECT
count(A.gross_c) AS cnt,
SUM(A.gross_c) AS Gross_c,
B.store_name
FROM hr_location_c_verified A
JOIN hr_stores B ON A.c_location = B.id
WHERE A.c_ref_fkid IS NULL
GROUP BY A.c_location
I am executing this query, the output result coming correct, but count showing wrong.
Please help me.

It's likely because of your JOIN, producing more rows.
One way is to use the DISTINCT keyword.
SELECT
count(DISTINCT A.gross_c) AS cnt,
SUM(A.gross_c) AS Gross_c,
B.store_name FROM hr_location_c_verified A
JOIN hr_stores B ON A.c_location = B.id
WHERE A.c_ref_fkid IS NULL
GROUP BY A.c_location

Related

SELECT query with JOIN returns duplicate of each row

I am running a SELECT query to return addresses in a table associated with a certain "applicant code" and I'd like to join a table to also return (in the same row) the name of that applicant.
Therefore my query as of now is
SELECT a.id, a.created_at, a.updated_at, a.code, a.applicant_code, a.form_code, a.address_line_1, a.address_line_2, a.town_city, a.county_state, a.country, a.post_code, a.start_date, a.end_date, a.type, ap.first_name, ap.last_name
FROM sfs_addresses a
JOIN sfs_personal_details ap ON a.form_code = ap.form_code
WHERE a.form_code = ? AND a.applicant_code = ?
The query works, and I get the right columns and values in each row, but it returns 2 of each so like
ID
===
1
1
2
2
3
3
4
4
If I remove the JOIN it works fine. I have tried adding DISTINCT (makes no difference) I'm lost.
EDIT: Based on this answer and the comments, the OP realized that the JOIN condition should be on applicant_code rather than form_code.
You have duplicates in the second table based on the JOIN key you are using (I question if the JOIN is correct).
If you just want one row arbitrarily, you can use row_number():
SELECT a.*, ap.first_name, ap.last_name
FROM sfs_addresses a JOIN
(SELECT ap.*,
ROW_NUMBER() OVER (PARTITION BY ap.form_code ORDER BY ap.form_code) as seqnum
FROM sfs_personal_details ap
) ap
ON a.form_code = ap.form_code
WHERE a.form_code = ? AND a.applicant_code = ?;
You can replace the columns in the ORDER BY with which result you want -- for instance the oldest or most recent.
Note: form_code seems like an odd JOIN column for a table called "personal details". So, you might just need to fix the JOIN condition.
relation between 2 tables one to many to return non duplicate use distinct
SELECT distinct a.id, a.created_at, a.updated_at, a.code, a.applicant_code, a.form_code, a.address_line_1, a.address_line_2, a.town_city, a.county_state, a.country, a.post_code, a.start_date, a.end_date, a.type, ap.first_name, ap.last_name
FROM sfs_addresses a
JOIN sfs_personal_details ap ON a.form_code = ap.form_code
WHERE a.form_code = ? AND a.applicant_code = ?

Redshift - SQL Left Join does not work with correlated subquery and aggregated function

I am quite new to Redshift SQL and have been trying to figure out what's wrong with my syntax.
My task is to join 2 tables: question and user via left join as I want to retain all values from table question.
At the moment it throws the following error message: [Amazon](500310) Invalid operation: This type of correlated subquery pattern is not supported yet; when I use left join. On the other hand, when I change the code to join it works just fine. I suspect this is because I have an aggregated function and logical expression within my subquery that makes my left join an inner join.
But as I mentioned above, I need to retain all values from table question.
Below is my code
select
qa.user_id as user_email,
i.timestamp as session_login_time,
qa.timestamp as question_ask_time,
qa.question_id,
qa.question
from
schema1.question as qa
left join
schema1.user as i
on
qa.user_id = i.email
and
i.timestamp =
(select
max(timestamp)
from schema1.user
where
timestamp <= qa.timestamp)
where user_email <> 'tester' and user_email not like '%tester.com'
group by qa.user_id, i.timestamp, qa.timestamp, qa.question_id, qa.question
The purpose of the subquery is to get the closest session_login_time to each of the question_ask_time. So, multiple rows of question can have the same session_login_time value.
Could anybody please help me identify what I am missing from my code above? How do I make my left join works?
Thank you so much!
I guess that should get you the same results without involving a sub query
select
qa.user_id as user_email,
max(i.timestamp) as session_login_time,
qa.timestamp as question_ask_time,
qa.question_id,
qa.question
from schema1.question as qa
left join schema1.user as i
on qa.user_id = i.email
and i.timestamp <= qa.timestamp
where qa.user_id <> 'tester' and qa.user_id not like '%tester.com'
group by qa.user_id, qa.timestamp, qa.question_id, qa.question

Group Concat from a select statement

I am not sure if my method is possible, but i'm trying to do a group_concat on a select statement that concats 2 fields. I get the error: Subquery returns more than 1 row each time. Can anyone help me as to a solution, or better way around this.
select t.recnum, (select group_concat((select concat(b.origtests,'^', d.name) as testing
from order_origtests b
join profile c on c.code = b.origtests
join department d on d.recnum = c.dept
)))
FROM order_ t
You don't put SELECT inside GROUP_CONCAT. It should be
select t.recnum, (
select group_concat(concat(b.origtests,'^', d.name))
from order_origtests b
join profile c on c.code = b.origtests
join department d on d.recnum = c.dept
) AS testing
FROM order_ t
Note that your subquery isn't correlated to anything in t, so you'll get the same testing column for every recnum.

MySQL avoiding GROUP BY columns from different tables

I've the following query that does a group by on 2 columns from different tables. I understand this can cause performance issues. I'm unsure how to go about optimizing this. Any help is greatly appreciated!
Query
SELECT tableA.col AS tableAcol,
tableB.col AS tableBcol,
SUM(tableB.count) AS total
FROM tableB, tableA
WHERE tableB.uid = tableA.uid
AND tableA.eid=?
GROUP BY tableA.col, tableB.col
You can use a subquery that performs partial sums, to reduce the size of the JOIN that sum in the outer query.
SELECT tableA.col AS tableAcol
tableBgrouped.col AS tableBcol,
SUM(tableBgrouped.count) AS total
FROM tableA
JOIN (SELECT uid, col, SUM(count) AS count
FROM tableB
GROUP BY uid, col) AS tableBgrouped
ON tableA.uid = tableBgrouped.uid
WHERE tableA.eid = ?
GROUP BY tableAcol, tableBcol
SELECT A.`col` AS tableAcol
B.`col` AS tableBcol,
SUM(B.`count`) AS total
FROM tableA A
JOIN (SELECT B1.`uid`, B1.`col`, SUM(B1.`count`) AS count
FROM tableB B
GROUP BY B1.`uid`, B1.`col`) AS B
ON A.`uid` = B.`uid`
WHERE A.`eid` = ?
GROUP BY A.`col`, B.`col`

What is wrong with my query on Access 2010?

I have this query on Access 2010 (accdb) which is working perfectly fine:
SELECT b.category_name, a.item_name,
(SELECT COUNT(*) FROM tbl_stock_receiving AS x WHERE x.safe_stock_id = a.ID) AS received,
(SELECT COUNT(*) FROM tbl_stock_issuance AS y WHERE y.stock_receiving_id = a.ID) AS issued,
(received-issued) AS on_hand, a.safe_stock
FROM tbl_safe_stock AS a INNER JOIN tbl_category AS b
ON a.category_id = b.id
ORDER BY a.item_name;
Now, I need to modify it to include a simple WHERE statement
...
ON a.category_id = b.id
WHERE a.safe_stock > on_hand
ORDER BY a.item_name;
...
When I run the query, Access keeps popping up for a parameter value for
on_hand
on_hand is an Alias as you can see on
(received-issued) AS on_hand
What could be wrong in my query?
You've defined on_hand as the name of an output column, but the SQL parser isn't clever enough to go back through your query and "reverse engineer" where on_hand came from. Therefore, you'd need to use something like WHERE a.safe_stock > (received - issued), but they are aliases for output columns, too.
So try wrapping the whole thing up as a subquery and then applying the WHERE and ORDER BY clauses afterward:
SELECT * FROM
(
SELECT b.category_name, a.item_name,
(SELECT COUNT(*) FROM tbl_stock_receiving AS x WHERE x.safe_stock_id = a.ID) AS received,
(SELECT COUNT(*) FROM tbl_stock_issuance AS y WHERE y.stock_receiving_id = a.ID) AS issued,
(received-issued) AS on_hand, a.safe_stock
FROM tbl_safe_stock AS a INNER JOIN tbl_category AS b
ON a.category_id = b.id
)
WHERE safe_stock > on_hand
ORDER BY item_name
Edit
The suggestion above resulted in a "Query is too complex" error, so my next suggestion was to save the original query as [StockCheckBaseQuery] and then do
SELECT * FROM StockCheckBaseQuery WHERE safe_stock > on_hand ORDER BY item_name
That appears to have been successful.