multiple statements to select distinct rows - mysql

I'm completely new to SQL. I have a table with multiple rows for the same ID (Alpha_code).
I want to query this table to provide only 1 row for each Alpha_code.
I need it to first select the newest row if rows have been added on different (contact_date).
I have found the statement below does this no problem.
SELECT m.*
FROM (SELECT Alpha_code, max(Contact_date) AS MaxDate FROM contactsNTH GROUP BY Alpha_code)
AS mm INNER JOIN contactsNTH AS m ON (mm.MaxDate = m.Contact_Date) AND (mm.Alpha_code = m.Alpha_code)
However there are other multiple rows that were entered on the same (contact_date). I'm not sure how to add more code to then only show 1 of the multiple rows remaining.
I've tried the Select Distinct statement but it didn't work.
Any assistance would be appreciated. If I can answer this myself in the meantime I'll post the answer
thanks, shaun
This thread is close to what I'm asking but I find the answer confusing.
How To Select Distinct Row Based On Multiple Fields 4

Assuming your schema as given here :- http://sqlfiddle.com/#!2/4e6ff/2
You can use the following query
SELECT c1.Alpha_code,c1.Contct_date from contactsNTH as c1
LEFT JOIN
contactsNTH as c2
ON
c1.Alpha_code = c2.Alpha_code
AND
(c1.Contct_date > c2.Contct_date) group by c1.Alpha_code
This query doesn't works in Standard SQL because it says, "a query that includes a GROUP BY clause cannot refer to non aggregated columns in the select list that are not named in the GROUP BY clause"
Try using this query
SELECT c1.Alpha_code,MAX(c1.Contct_date) as contact_date from contactsNTH as c1
LEFT JOIN
contactsNTH as c2
ON
c1.Alpha_code = c2.Alpha_code
AND
(c1.Contct_date > c2.Contct_date) group by c1.Alpha_code
both will provide the same result http://sqlfiddle.com/#!2/4e6ff/4

You can do it easily by using inner query. Sql Fiddle Demo
SELECT Alpha_code, Contact_date AS MaxDate FROM contactsNTH AS t WHERE
Contact_date = (SELECT MAX(Contact_date) FROM contactsNTH
WHERE Alpha_code=t.Alpha_code)
I wrote a query using simply group by and having maximum date but it failed Then I wrote these words in google select group by having max and found the result. this is an example guide for you to get such problems fixed quickly

Related

MySQL subquery in select with link to outer field

I convert an old software (that use MS-ACCESS MDB) to mySQL.
I have a query that takes long time to run (actualy I break running after 5 minutes of waiting)
How can I write it?
SELECT pa_ID, pa_PRODUCT_ID, pr_ID,pr_NAME,Sum(pa_KILOS) as IN_KILOS,
(select sum(pl_KILOS) from POLHSH where POLHSH.pl_PRODUCT_ID = pa_PRODUCT_ID and POLHSH.pl_PARALABH_ID = pa_ID) as OUT_KILOS From PARALABH, PRODUCTS WHERE pa_company_id=1 GROUP BY pa_ID, pa_PRODUCT_ID,pr_ID, pr_NAME HAVING pa_ID=241 and pr_id=pa_PRODUCT_ID
Thanks in advance
Consider avoiding the correlated subquery which runs a SUM separately for each row and use a join of two aggregate queries each of which runs SUM once by grouping fields. Additionally, use explicit joins, the current SQL standard in joining tables/views.
Please adjust column aliases and names to actuals as assumptions were made below.
SELECT t1.*, t2.OUT_KILOS
FROM
(SELECT pa.pa_ID,
pa.pa_PRODUCT_ID,
pr.pr_ID,
pr.pr_NAME,
SUM(pa.pa_KILOS) AS IN_KILOS
FROM PARALABH pa
INNER JOIN PRODUCTS pr
ON pr.pr_id = pa.pa_PRODUCT_ID
WHERE pa.pa_company_id = 1
GROUP BY pa.pa_ID,
pa.pa_PRODUCT_ID,
pr.pr_ID,
pr.pr_NAME
HAVING pa.pa_ID = 241
) AS t1
INNER JOIN
(SELECT POLHSH.pl_PRODUCT_ID,
POLHSH.pl_PARALABH_ID
SUM(pl_KILOS) As OUT_KILOS
FROM POLHSH
GROUP BY POLHSH.pl_PRODUCT_ID,
POLHSH.pl_PARALABH_ID
) AS t2
ON t2.pl_PRODUCT_ID = t1.pa_PRODUCT_ID
AND t2.pl_PARALABH_ID = t1.pa_ID

Why INNER JOIN dont not work correct?

I have one SQL query with INNER JOINS. I need to get all offers from table offers.
Table offers is empty now. But the following query returns one row with NULL field.
Why is it returned? How to fix that? I need to return 0 rows if table is empty.
Query:
select *, SUM(offers.price * announcement_product.amount) AS total, announcements.user_id AS creator_ann, announcements.id AS ann_id,
announcements.delivery AS deliveryAnn, announcements.payment AS
paymentAnn, SUM(announcement_product.amount) AS amount,
announcement_product.name as name_product
from `offers`
inner join `announcements` on `announcements`.`id` = `offers`.`announcement_id`
inner join `announcement_product` on `offers`.`announcement_product_id` = `announcement_product`.`id`
inner join `countries` on `countries`.`id` = `announcements`.`country`
where `offers`.`user_id` = 1 and `offers`.`status` = 1 and `offers`.`deleted_at` is null
You're using the aggregate function SUM(), but you don't have any GROUP BY clause.
When you do that you are instructing MySQL to add up all the row values in the column you mention in SUM(). It will do that even if there are no rows to add up.
For best results you should study up on the GROUP BY function and how to use it with SUM(). It's hard to guess what you want from your query.
I'm not sure, but I don't think
select *, ..
when there's multiple tables in the query is valid.
Try
select offers.*,..
This how Your select structure should be :
Select
Id,
Sku,
Sum(Onhand),
Sum(price)
From mytable
Where mytable Onhand > 0
Group by
Id,Sku
If you are going to use aggregate function such as Max,Sum,Min,....
you need to use group by for other table fields that your using in the select part.

Grouping method

I am working on a query with the following format:
I require all the columns from the Database 'A', while I only require the summed amount (sum(amount)) from the Database 'B'.
SELECT A.*, sum(B.CURTRXAM) as 'Current Transaction Amt'
FROM A
LEFT JOIN C
ON A.Schedule_Number = C.Schedule_Number
LEFT JOIN B
ON A.DOCNUMBR = B.DOCNUMBR
ON A.CUSTNMBR = B.CUSTNMBR
GROUP BY A
ORDER BY A.CUSTNMBR
My question is regarding the grouping statement, database A has about 12 columns and to group by each individually is tedious, is there a cleaner way to do this such as:
GROUP BY A
I am not sure if a simpler way exists as I am new to SQL, I have previously investigated GROUPING_ID statements but thats about it.
Any help on lumped methods of grouping would be helpful
Since the docnumber is the primary key - just use the following SQL:
SELECT A.*, sum(B.CURTRXAM) as 'Current Transaction Amt'
FROM A
LEFT JOIN C
ON A.Schedule_Number = C.Schedule_Number
LEFT JOIN B
ON A.DOCNUMBR = B.DOCNUMBR
ORDER BY RM20401.CUSTNMBR
GROUP BY A.DOCNUMBR

My SQL query is not optimised neither it looks good, please have a look

There is a table called m_techno_idea(stores ideas), m_techno_idea_moderator_vote(moderator votes), and m_techno_idea_user_vote(for uservotes). User vote is only 1 while moderator vote is between 1 -5 and is stored in the column named votes. So I need to get the total no. of votes in a single query. I don't want a nested query.
My Attempts:
Attempt 1:
SELECT
COUNT(DISTINCT TIUV.PK_ID) + IFNULL((SUM(TIMV.VOTES)),0) AS VOTES
FROM
M_TECHNO_IDEA TI
LEFT OUTER JOIN
M_TECHNO_IDEA_MODERATOR_VOTE TIMV
ON
TIMV.FK_TECHNO_IDEA_ID=TI.PK_ID
LEFT OUTER JOIN
M_TECHNO_IDEA_USER_VOTE TIUV
ON
TIUV.FK_TECHNO_IDEA_ID=TI.PK_ID
WHERE
TI.PK_ID=2
Here distinct keyword helps me to have distinct rows for user votes but for moderator votes I can't use distinct, as the votes can be same in many rows.This gives me wrong results.
Attempt 2:
SELECT (select count(TIUV.PK_ID) FROM M_TECHNO_IDEA_USER_VOTE TIUV
WHERE TIUV.FK_TECHNO_IDEA_ID=2) +
(select sum(TIMV.VOTES) FROM M_TECHNO_IDEA_moderator_VOTE TIMV
WHERE TIMV.FK_TECHNO_IDEA_ID=2) AS VOTES
Attempt 2 gives me correct results but the query doesn't look good. I have tried group by also but it didn't help me too. Any Help will be appreciated.
Attempt 3:
SELECT
COUNT(DISTINCT TIUV.PK_ID) + IFNULL(MODVOTES.VOTES, 0) AS VOTES
FROM
(SELECT
TIMV.FK_TECHNO_IDEA_ID, SUM(TIMV.VOTES) VOTES
FROM
M_TECHNO_IDEA_MODERATOR_VOTE TIMV
GROUP BY TIMV.FK_TECHNO_IDEA_ID) MODVOTES
LEFT OUTER JOIN
M_TECHNO_IDEA_USER_VOTE TIUV ON TIUV.FK_TECHNO_IDEA_ID = MODVOTES.FK_TECHNO_IDEA_ID
WHERE
TIUV.FK_TECHNO_IDEA_ID = 2
This attempt also gives me the correct result. I had to place a nested sub query. If a better solution comes, it would be appreciated.
To achieve this, "I simply want to get the sum of two votes stored in two different tables", use a derived table. Here is the general idea.
select sum(votes) totalvotes
from (
select count(something) votes
from TheFirstTable
where whatever
union
select count(something) votes
from TheSecondTable
where whatever ) ThisIsCalledADerivedTable
You can put together the derived table to suit your requirements.
Your second attempt is good, except you can clean it up a lot by removing unnecessary aliases, using consistent letter-casing and a little formatting:
SELECT
(SELECT COUNT(*) FROM M_TECHNO_IDEA_USER_VOTE WHERE FK_TECHNO_IDEA_ID = 2) +
(SELECT SUM(VOTES) FROM M_TECHNO_IDEA_moderator_VOTE WHERE FK_TECHNO_IDEA_ID = 2)
AS VOTES

Unable to union Select and Innerjoin

I've hit a dilemma when developing on a system for the company and the project manage is not about!
SELECT clients_owner.Name, clients_owner.`number`, clients_shops.Shopname, clients_shops.PostCode, clients_shops.Location
FROM clients_shops inner join clients_owner ON
clients_owner.ShopID = clients_shops.ShopID
UNION
SELECT clients_fans.Fan
FROM clients_shops inner join clients_fans ON
clients_shops.ShopID = clients_fans.ShopID
The following query is returning the following error:
1222 - The used SELECT statements have a different number of columns
But using this as an example: Mysql JOIN (multiple) tables is marked as the answer, so the queries are obviously valid. Where have I gone wrong?
Whereas the following join to merge two tables:
SELECT
clients_owner.Name, clients_owner.Number, clients_shops.Shopname, clients_shops.PostCode,
clients_shops.Location FROM clients_shops INNER JOIN clients_owner on
clients_owner.ShopID = clients_shops.ShopID
Works without a hitch
To use UNION you must have:
The same number of columns in both requests.
Columns in corresponding positions of each SELECT statement should have the same data type.
You have 5 columns in the 1-st request:
clients_owner.Name,
clients_owner.`number`,
clients_shops.Shopname,
clients_shops.PostCode,
clients_shops.Location
and 1 column in the 2-nd request:
clients_fans.Fan
http://dev.mysql.com/doc/refman/5.0/en/union.html
Union means your are adding the same columns under the existing columns you alreday have. In your case you have 5 columns in the first query and 1 in the second:
|1|2|3|4|5
|1|
doesn't match.
What you need is another join:
SELECT clients_owner.name,
clients_owner.`number`,
clients_shops.shopname,
clients_shops.postcode,
clients_shops.location,
clients_fans.fan
FROM clients_shops
INNER JOIN clients_owner
ON clients_owner.shopid = clients_shops.shopid
LEFT JOIN clients_fans
ON clients_fans.shopid = clients_shops.shopid
If you are using UNION the number of columns in both the select statement should be equal.
Each SELECT statement within the UNION must have the same number of columns