I have a little question about a problem with a SQL query. I've written a query to get some records and the number of occurences of those records. The problem is that I'd like to join two tables so I can get some values instead of foreign keys. This is my actual query (which I think is wrong because there is no joins in the result) :
SELECT date, heure_debut, heure_fin, Event_id,
horaire_id, local_id, enseignant_id, COUNT(*) doublons
FROM `reservations`
INNER JOIN `events` ON `events`.`id` = `reservations`.`Event_id`
INNER JOIN `couleurs` ON `couleurs`.`id` = `events`.`couleur_id`
GROUP BY date,
heure_debut,
heure_fin,
Event_id,
horaire_id,
local_id,
enseignant_id
HAVING COUNT(*) > 1 OR COUNT(*) = 1
Thank you for your answers.
Sort of a wild guess based on the OP's description of his intent.
Assuming that table events has a column titre that is an AK, the following modifications to the original query might mirror this intent. Instead of the event id it shows its name:
SELECT date, heure_debut, heure_fin, `events`.titre,
horaire_id, local_id, enseignant_id, COUNT(*) doublons
FROM `reservations`
INNER JOIN `events` ON `events`.`id` = `reservations`.`Event_id`
INNER JOIN `couleurs` ON `couleurs`.`id` = `events`.`couleur_id`
GROUP BY date,
heure_debut,
heure_fin,
`events`.titre,
horaire_id,
local_id,
enseignant_id
HAVING COUNT(*) > 0
;
Related
I have a table here in which I want to write a SELECT query in SQL Server that allows me to get the following:
For each unique combination of SalesPerson x Country, get only the rows with the latest Upload_DateTime
However, I am trying to do a group-by and inner join, but to no avail. My code is something like this:
SELECT t1.[SalesPerson], t1.[Country], MAX(t1.[Upload_DateTime]) as [Upload_DateTime]
FROM [dbo].[CommentTable] AS t1
GROUP BY t1.[SalesPerson], t1.[Country]
INNER JOIN SELECT * FROM [dbo].[CommentTable] as t2 ON t1.[SalesPerson] = t2.[SalesPerson], t1.[Country] = t2.[Country]
It seems like the GROUP BY needs to be done outside of the INNER JOIN? How does that work? I get an error when I run the query and it seems my SQL is not right.
Basically, this subquery will fetch the person, the country and the latest date:
SELECT
SalesPerson, Country, MAX(uplodaed_datetime)
FROM CommentTable
GROUP BY SalesPerson, Country;
This can be used on a lot of ways (for example with JOIN or with an IN clause).
The main query will add the remaing columns to the result.
Since you tried a JOIN, here the JOIN option:
SELECT
c.id, c.SalesPerson, c.Country,
c.Comment, c.uplodaed_datetime
FROM
CommentTable AS c
INNER JOIN
(SELECT
SalesPerson, Country,
MAX(uplodaed_datetime) AS uplodaed_datetime
FROM CommentTable
GROUP BY SalesPerson, Country) AS sub
ON c.SalesPerson = sub.SalesPerson
AND c.Country = sub.Country
AND c.uplodaed_datetime = sub.uplodaed_datetime
ORDER BY c.id;
Try out: db<>fiddle
I need to do two counts of a column based on the content of another column in a different table.
SELECT WMTRANSACTIONHEADER.TRANSACTIONTYPE
, IMITEM.ITEMSUPCCODE
, COUNT(IMITEM.ITEMSUPCCODE) AS 'Shipment'
, COUNT(IMITEM.ITEMSUPCCODE) AS 'Reciept'
, CAST(MTRANSACTIONHEADER.TRANSACTIONDATE AS DATE) AS DATE
FROM WMTRANSACTIONHEADER
INNER JOIN WMTRANSACTIONDETAIL ON WMTRANSACTIONHEADER.ROWID = WMTRANSACTIONDETAIL.R_TRANSACTIONHEADER
INNER JOIN IMITEM ON WMTRANSACTIONDETAIL.R_ITEM = IMITEM.ROWID
Forgive me for how unreadable it is, but generally, I'm trying to count ITEMSUPCCODE based on whether TRANSACTIONTYPE is either an 'R' or an 'S'. Any tips/ideas would be great!
EDIT:
Unfortunately I underestimated this task and the importance of other fields. So let me explain this more in depth. I am making a report that counts the daily ITEMSUPCCODE fields. There are 8 ITEMSUPCCODE fields that are possible, and we want a count of each one. So the perfect report would group all the transactions in a day, then group by each entry in ITEMSUPCCODE, and then count each entry in ITEMSUPCCODE, based on what is in TRANSACTIONTYPE. I apologize for not being clear, I thought the counting part was the only issue I had!
Something like this if I am getting your question right: Below query is not tested
With tmp AS(Select WMTRANSACTIONHEADER.TRANSACTIONTYPE, IMITEM.ITEMSUPCCODE,
CONVERT(DATETIME, CONVERT(DATE, MTRANSACTIONHEADER.TRANSACTIONDATE)) Date;
FROM WMTRANSACTIONHEADER INNER JOIN WMTRANSACTIONDETAIL
ON WMTRANSACTIONHEADER.ROWID = WMTRANSACTIONDETAIL.R_TRANSACTIONHEADER
INNER JOIN IMITEM ON WMTRANSACTIONDETAIL.R_ITEM = IMITEM.ROWID
WHERE TRANSACTIONTYPE in ('R', 'S'))
select count(ITEMSUPCCODE) , Date, Transactiontype
from tmp
group by Date, Transactiontype
You can change count(ITEMSUPCCODE) or count(DISTINCT ITEMSUPCCODE) based on your requirement.
Here's a different approach with the result in rows instead of columns.
It also allows you to count how many distinct IMITEM.ITEMSUPCCODE there are in your table
Select count(distinct IMITEM.ITEMSUPCCODE), --count of distinct values in the group
count(IMITEM.ITEMSUPCCODE), --non-distinct values
TRANSACTIONTYPE
FROM WMTRANSACTIONHEADER
INNER JOIN WMTRANSACTIONDETAIL
ON WMTRANSACTIONHEADER.ROWID = WMTRANSACTIONDETAIL.R_TRANSACTIONHEADER
INNER JOIN IMITEM
ON WMTRANSACTIONDETAIL.R_ITEM = IMITEM.ROWID
where TRANSACTIONTYPE in ('R', 'S')
group by TRANSACTIONTYPE
In cases like this, I often use a subquery like this:
select
NameLast,
(select count(*) from Paychecks where Paychecks.EmployeeID = Employees.ID) As PaycheckCount
from Employees
The inner join isn't needed for the subtable.
Reworking your original query, I think this should work:
SELECT WMTRANSACTIONHEADER.TRANSACTIONTYPE, IMITEM.ITEMSUPCCODE, COUNT(IMITEM.ITEMSUPCCODE) AS 'Shipment',
(SELECT COUNT(ITEMSUPCCODE) FROM IMITEM WHERE WMTRANSACTIONDETAIL.R_ITEM = IMITEM.ROWID) AS 'Reciept'
FROM WMTRANSACTIONHEADER INNER JOIN WMTRANSACTIONDETAIL ON
WMTRANSACTIONHEADER.ROWID = WMTRANSACTIONDETAIL.R_TRANSACTIONHEADER
Does this work for you?
select
picks.`fbid`,
picks.`time`,
categories.`name` as cname,
options.`name` as oname,
users.`name`
from
picks
left join categories
on (categories.`id` = picks.`cid`)
left join options
on (options.`id` = picks.oid)
left join users
on (users.fbid = picks.`fbid`)
order by
time desc
that query returns a result that like:
my question is.... I would like to modify the query to select only DISTINCT fbid's. (perhaps the first row only sorted by time)
can someone help with this?
select
p2.fbid,
p2.time,
c.`name` as cname,
o.`name` as oname,
u.`name`
from
( select p1.fbid,
min( p1.time ) FirstTimePerID
from picks p1
group by p1.fbid ) as FirstPerID
JOIN Picks p2
on FirstPerID.fbid = p2.fbid
AND FirstPerID.FirstTimePerID = p2.time
LEFT JOIN Categories c
on p2.cid = c.id
LEFT JOIN Options o
on p2.oid = o.id
LEFT JOIN Users u
on p2.fbid = u.fbid
order by
time desc
I don't know why you originally had LEFT JOINs, as it appears that all picks must be associated with a valid category, option and user... I would then remove the left, and change them to INNER joins instead.
The first inner query grabs for each fbid, the FIRST entry time which will result in a single entity for the FBID. From that, it re-joins to the picks table for the same ID and timeslot... then continues for the rest of the category, options, users join criteria of that single entry.
2 options, you could write a group by clause.
Or you could write a nested query joined back to itself to get pertinent info.
Nested aliased table:
SELECT
n.fBids
FROM
MyTable t
INNER JOIN
(SELECT DISTINCT fBids
FROM MyTable) n
ON n.ID = t.ID
Or group by option
SELECT fBId from MyTable
GROUP BY fBID
select picks.`fbid`, picks.`time`, categories.`name` as cname,
options.`name` as oname, users.`name` from picks left join categories
on (categories.`id` = picks.`cid`) left join options on (options.`id` = picks.oid)
left join users on (users.fbid = picks.`fbid`)
order by time desc GROUP BY picks.`fbid`
select
picks.fbid,
MIN(picks.time) as first_time,
MAX(picks.time) as last_time
from
picks
group by
picks.fbid
order by
MIN(picks.time) desc
However, if you want only distinct fbid's you cannot display cname and other columns at the same time.
I have 3 tables, where the first one's primary key, is the foreign key in the other 2.
I want to extract one field from the first table, and then a count from the other 2, all joined using the pk and fk. This is what I have so far:
SELECT MBDDX_STUDY.STUDY_NAME, COUNT(MBDDX_EXPERIMENT.STUDY_ID) AS NUMBER_OF_EXPERIMENTS
FROM MBDDX_STUDY
INNER JOIN MBDDX_EXPERIMENT
ON MBDDX_STUDY.ID=MBDDX_EXPERIMENT.STUDY_ID
INNER JOIN (SELECT COUNT(MBDDX_TREATMENT_GROUP.GROUP_NO) AS NUMBER_OF_GROUPS
FROM MBDDX_TREATMENT_GROUP)
ON MBDDX_TREATMENT_GROUP.STUDY_ID = MBDDX_STUDY.ID
group by MBDDX_STUDY.STUDY_NAME, MBDDX_TREATMENT_GROUP.STUDY_ID
But, i get an error saying that the MBDDX_TREATMENT_GROUP.STUDY_ID , in the penultimate line is an invalid indentifier. It is a correct table.
Any advise please.
Thanks.
You're getting the error because that column is not in your SELECT, so it can't GROUP BY a field it doesn't have.
The subquery syntax doesn't seem to make any sense to me. You've made a query that counts all rows of MBDDX_TREATMENT_GROUP, independently of the STUDY_ID, and then tries to join it into the table with a join condition that doesn't refer to anything in the subquery's results (and can't, without an alias).
Why not use a simple join? Assuming MBDDX_EXPERIMENT also has a primary key ID, you can do it with a COUNT-DISTINCT:
SELECT
MBDDX_STUDY.ID, MBDDX_STUDY.STUDY_NAME,
COUNT(DISTINCT MBDDX_EXPERIMENT.ID) AS NUMBER_OF_EXPERIMENTS
COUNT(DISTINCT MBDDX_TREATMENT_GROUP.GROUP_NO) AS NUMBER_OF_GROUPS
FROM
MBDDX_STUDY
INNER JOIN MBDDX_EXPERIMENT ON MBDDX_EXPERIMENT.STUDY_ID=MBDDX_STUDY.ID
INNER JOIN MBDDX_TREATMENT_GROUP ON MBDDX_TREATMENT_GROUP.STUDY_ID=MBDDX_STUDY.ID
GROUP BY
MBDDX_STUDY.ID, MBDDX_STUDY.STUDY_NAME
(MBDDX_STUDY.STUDY_NAME technically shouldn't be necessary to include in the GROUP BY expression according to ANSI SQL as it has a functional dependency on STUDY_ID. However it is necessary on Oracle, which can't spot the dependency.)
You don't need to group by this field (MBDDX_TREATMENT_GROUP.STUDY_ID). It should be just group by MBDDX_STUDY.STUDY_NAME
If my understanding is correct,You need a record from first table and have the count of related records in the other two tables.Here is the answer
SQL:Getting count from many tables for a user record in USER table.Whats the best approach?
It looks like you need to alias the second subquery and need to include something to join on.
It also looks like you aren't using the count you have in the subquery as well.
Try this out:
SELECT MBDDX_STUDY.STUDY_NAME
, COUNT(MBDDX_EXPERIMENT.STUDY_ID) AS NUMBER_OF_EXPERIMENTS
FROM MBDDX_STUDY
INNER JOIN MBDDX_EXPERIMENT
ON MBDDX_STUDY.ID=MBDDX_EXPERIMENT.STUDY_ID
INNER JOIN (SELECT STUDY_ID, COUNT(MBDDX_TREATMENT_GROUP.GROUP_NO) AS NUMBER_OF_GROUPS
FROM MBDDX_TREATMENT_GROUP GROUP BY MBDDX_TREATMENT_GROUP.STUDY_ID) xx
ON xx.STUDY_ID = MBDDX_STUDY.ID
GROUP BY MBDDX_STUDY.STUDY_NAME, xx.STUDY_ID
For what you really want to do, you want OUTER JOINs.
WITH number_of_experiments
AS ( SELECT study_id
, count ( * ) CNT
FROM MBDDX_EXPERIMENT
group by study_id )
, number_of_groups
as ( select study_id
, count ( * ) CNT
FROM mbddx_treatment_group
group by study_id )
select study_name
, coalesce(noex.cnt,0)
, coalesce(notr.cnt,0)
from mbddx_study
outer join number_of_experiments
as noex
using ( study_id )
outer join number_of_groups
as nogr
using ( study_id )
select distinct Franchise.FranchiseName, Franchise.Initials, Franchise.StoreNo, AccountCancellation_Process.Store_Num
FROM FranchiseData
INNER JOIN AccountCancellation_Process
on FranchiseData.StoreNo = AccountCancellation_Process.Store_Num
select count(*) from AccountCancellation_Process where Store_Num = '1234'
select count(*) from AccountCancellation_Process where Store_Num = '1234' and Progress is not null
I want to combine the count(*) from AccountCancellation_Process into the above inner join statement so the query will give me the result of FranchiseName, Initials, StoreNo from Franchise table and Store_Num from the AccountCancellation_Process with the total records and total record with Progress column not null.
how do you combine the query result with count function result?
thank.
Like this I think is what you want.
I created two table value correlated subqueries to get the data based on the stored number in the inner join table. Then I join them based on the store number. That way the distinct will work. But you might also be able to do the counts in the select part with using just correlated subqueries. I was worried the distinct might not work though.
SELECT DISTINCT Franchise.FranchiseName, Franchise.Initials, Franchise.StoreNo, acp.Store_Num, total_count.Total_Count, progress_count.Progress_Count
FROM FranchiseData
INNER JOIN AccountCancellation_Process AS acp ON (FranchiseData.StoreNo = acp.Store_Num)
INNER JOIN (SELECT Store_Num, COUNT(*) AS Total_Count FROM AccountCancellation_Process WHERE Store_Num = acp.Store_Num) AS total_count ON (acp.Store_Num = total_count.Store_Num)
INNER JOIN (SELECT Store_Num, COUNT(*) AS Progress_Count FROM AccountCancellation_Process WHERE Store_Num = acp.Store_Num AND Progress IS NOT NULL) AS progress_count ON (acp.Store_Num = progress_count.Store_Num)
Alias the count(*) then use a Sum(alias)