how to merge count values in sql - mysql

I am trying to update all city values of the table team as: “city” + “ #p” + “number of players” +” g” + “number of goals forward” (e.g. “Tokyo #p25 g74”).
I tried to do this and have this two queries. One for get the number of players and one for get the number of goals.
Query for the number of players:
select t.city + '#p' + CONVERT(varchar(10), count(pt.playerId)) + '#g'
from team t,
player_team pt
where pt.teamID = t.teamID
group By t.teamId,t.city
Query for the number of goals:
select count(*) totalgoals,
pt.teamID
from goals g,
player_team pt
where g.playerId = pt.playerId
group by pt.teamID
i couldn't merge theese two counts.
Help me out pls...
Also my tables hierarchy and fields like the shown below
player
(
playerID int,
firstName nvarchar(25),
lastName nvarchar(25),
nationality varchar(25),
birthDate smalldatetime,
age smallint,
position varchar(25)
)
team
(
teamID int,
name nvarchar(50),
city nvarchar(25)
)
player_team
(
playerID int,
teamID int,
season varchar(5)
)
match
(
matchID int,
homeTeamID int,
visitingTeamID int,
dateOfMatch smalldatetime,
week tinyint
)
goals
(
matchID int,
playerID int,
isOwnGoal bit,
minute tinyint
)
EDIT : Select query with the given below is worked well and give me the right results.But how can i update the table with this multiple records? When i try to update it as a subquery into update statement, it gives me compile error and complaining about multirecords...
Error:Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

Assuming your 2 queries are producing the desired results, try combining them with an an outer join and a subquery:
select pt.teamId,
t.city + ' #p' + CONVERT(varchar(10), count(pt.playerId))
+ ' g' + CONVERT(varchar(10), t2.totalgoals)
from team t
inner join player_team pt on pt.teamID = t.teamID
left join (
select count(*) totalgoals,
pt.teamID
from goals g inner join player_team pt on g.playerId = pt.playerId
group by pt.teamID
) t2 on t.teamid = t2.teamid
group By pt.teamId,t.city,t2.totalgoals
SQL Fiddle Demo

The simplest way probably is to use correlated subqueries to look up the values for each team:
SELECT t.city || ' #p' ||
CONVERT(varchar(10), (SELECT count(*)
FROM player_team
WHERE teamId = t.teamId))
|| ' #g ' ||
CONVERT(varchar(10), (SELECT count(*)
FROM goals
JOIN player_team USING (playerId)
WHERE teamId = t.teamId))
FROM team t

Try this:
SELECT a.city '#p' + CONVERT(varchar(10), a.playerCount) + '#g' + CONVERT(varchar(10), b.totalgoals)
FROM (SELECT t.teamId, t.city, count(pt.playerId) as playerCount
FROM team t JOIN player_team pt on (t.teamID = pt.teamID)
GROUP BY t.teamId, t.city)a JOIN
(SELECT pt.teamId, count(*) as totalgoals,
FROM goals g JOIN player_team pt on (g.playerId = pt.playerId)
GROUP BY pt.teamId) b ON (a.teamId = b.teamId)

Related

Without Count, Query patients who have more than two preconditions, Patientinformation and Preconditions are my tables, PatientID is the shared key

select Fname, Lname
from Patientinformation
where PatientID in (Select distinctrow PatientID
from Preconditions
where (Patientinformation.PatientID = Preconditions.PatientID)>=2
);
This shows no error, but I'm getting zero results
This shows no error, but I'm getting zero results
(Patientinformation.PatientID = Preconditions.PatientID) may be NULL, TRUE or FALSE which is treated as NULL, 1 or 0 respectively.
So (Patientinformation.PatientID = Preconditions.PatientID)>=2 is NULL >= 2, 0 >= 2 or 1 >= 2 - i.e. it is never TRUE.
how can I check if the PatientID matches more than one PreCondition, without using the count Function? – sandeep venkat
Why you want NOT to use COUNT()? – Akina
Part of my assignment. – sandeep venkat
Use, for example
SELECT DISTINCT t1.columns
FROM t1
JOIN t2 t21 ON t1.somecolumn = t21.somecolumn
JOIN t2 t22 ON t1.somecolumn = t22.somecolumn AND t21.id != t22.id
or
SELECT t1.columns
FROM t1
WHERE EXISTS ( SELECT NULL
FROM t2 t21
WHERE t1.somecolumn = t21.somecolumn
AND EXISTS ( SELECT NULL
FROM t2 t22
WHERE t21.somecolumn = t22.somecolumn
AND t21.id != t22.id ) )
You can get the patient ids using:
select PatientID
from Preconditions p
group by PatientID
having count(*) > 2;
Then you can combine this with the patient information. IN is fine (although it would not be my first choice):
select pi.Fname, pi.Lname
from Patientinformation pi
where pi.PatientID in (select p.PatientID
from Preconditions p
group by PatientID
having count(*) > 2
);

same colum name with different table id in mysql

tables
person_id (primary key)
phs_people (person_id,first_name,last_name)
phs_cutomers (person_id,company_name)
phs_waiters (person_id,commission)
person_id is key between them.
So my question how can retrive customers firstname and last name, waiter firstname and lastname via person_id?
SELECT
c.first_name AS customer_Fist_name,
c.last_name AS Customer_LastName,
c.first_name AS WaiterFirstName,
c.last_name AS Waiter_LastName,
invoice_number, amount_tendered, sale_time, DATE_FORMAT( sale_time, '%d-%m-%Y' ) AS sale_date, phs_sales.sale_id AS sale_id, SUM( item_unit_price * quantity_purchased * ( 1 - discount_percent /100 ) ) AS amount_due
FROM (
phs_sales
)
LEFT JOIN phs_people c ON c.person_id = phs_sales.customer_id
AND person_id = phs_sales.waiter_id
JOIN phs_sales_items ON phs_sales_items.sale_id = phs_sales.sale_id
LEFT JOIN (
SELECT sale_id, SUM( payment_amount ) AS amount_tendered
FROM phs_sales_payments
WHERE payment_type <> 'Check'
GROUP BY sale_id
) AS payments ON payments.sale_id = phs_sales.sale_id
GROUP BY sale_id
ORDER BY sale_time DESC
LIMIT 25
if I execute this query, I get the following error:
customer_Fist_name NULL,Customer_LastName NULL, WaiterFirstName NULL, Waiter_LastName NULL,
You want to do JOIN's two times on the same table but with different values (customer's data and waiter's data), but you just use a JOIN once and give both conditions there.
To fix this, your have to JOIN the phs_people-Table twice like this:
...
LEFT JOIN phs_people AS c1 ON c1.person_id = phs_sales.customer_id
LEFT JOIN phs_people AS c2 ON c2.person_id = phs_sales.waiter_id
...
and then select the correct data like this:
SELECT
c1.first_name AS customer_Fist_name,
c1.last_name AS Customer_LastName,
c2.first_name AS WaiterFirstName,
c2.last_name AS Waiter_LastName,
...
PS: With this query, you should still get multiple NULL-Values, that's because half of your phs_sales-Table is filled with empty fields...

Select table two times - not working

Actually I have the following database schema:
* events
id type player match
* players
id name
* matches
id date
The event type can be "A" for assistances or "G" for goals. I need to select the two types in the same query to calculate an offensive production (assistances + goals * 2).
The final result need to be:
year player assistances goals off_production
I have tried the following query, but it's not working (it's returning wrong data):
SELECT COUNT(assist.id) AS assistances, COUNT(goals.id) AS goals, (assistances + goals * 2) AS off_prod, p.name AS player, YEAR(m.date) AS year
FROM matches AS m, players AS p, events AS assist, events AS goals
WHERE assist.match = m.id AND
assist.type ="A" AND
assist.player = p.id AND
goals.match = j.id AND
goals.type ="G" AND
goals.player = p.id
GROUP BY year, player
ORDER BY year DESC, off_prod DESC
Thanks in advance
Try this....
SELECT assistances
,goals
,(A.assistances + A.goals * 2) AS off_prod
,player
,`YEAR`
FROM (
SELECT COUNT( CASE WHEN e.`type` ='A' THEN 1 ELSE NULL END) AS assistances
,COUNT( CASE WHEN e.`type` ='G' THEN 1 ELSE NULL END) AS goals
,p.`Name` AS player
,YEAR(m.`date`) AS `year`
FROM `players` AS p
INNER JOIN `events` AS e ON p.`id` = e.`player`
INNER JOIN `matches` AS m ON e.`match` = m.`id`
GROUP BY p.`name`, YEAR(m.`date`)
) A
ORDER BY A.`year` DESC, (A.assistances + A.goals * 2) DESC
Working Sql Fiddle

More than one Case in same query are generating more than one row

My problem is actually I have multiple tables and I'm using two case statements to generate one column for ARV1 and one for ICA1, but I need the results are generated in the same row. When I usecase, generate the two columns but the values are displayed in two rows. What am I missing?
the thing is, i have an invoice the table OINV and have the table INV5 that is the table with the Holding Taxes, i need to put on the same row the invoice with all the Holding Taxes in different columns that are applying on it, thanks
this is the example tables
CREATE TABLE Invoice
(
Id INT, InvoiceNumber VARCHAR(10), Total INT
)
INSERT INTO Invoice
VALUES
(1,'200000',100),
(2,'200001',200),
(3,'200002',500),
(4,'200003',700),
(5,'200004',200),
(6,'200005',100),
(7,'200006',300)
CREATE TABLE HoldingTaxes
(
Id INT, HoldingTaxCode VARCHAR(10),HoldedAmount INT)
)
INSERT INTO HoldingTaxes
VALUES
(1,'ARV1',20),
(1,'ARV2',30),
(1,'ARV3',35),
(2,'ICA1',20),
(2,'ARV1',10),
(1,'ICA3',50)
I want a query that returns something like this:
InvoiceNumber Total ARV1 ARV2 ARV3 ICA1 ICA2 ICA3
200000 100 20 30 35 null null 50
This is what i am trying to do with my real tables
SELECT T0.DocNum [No. Factura],
CASE
WHEN t5.WTCode ='ARV1' and (t5.U_Ret_ML <>0 AND t5.U_Ret_ML is not null)
THEN 'Perro1'
else NULL
end AS ARV1
,
CASE
WHEN t5.WTCode ='ICA1' and (t5.U_Ret_ML <>0 AND t5.U_Ret_ML is not null)
THEN 'Perro2'
else NULL
end AS ICA1
FROM OINV T0
INNER JOIN INV1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN OSLP T4 ON T0.SlpCode = T4.SlpCode
INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode
INNER JOIN OITW T3 ON T2.ItemCode = T3.ItemCode
INNER JOIN INV5 T5 ON T5.AbsEntry = T0.DocEntry
WHERE T1.WhsCode = T3.WhsCode`enter code here`
GROUP BY T0.DocNum,T0.DocDate,T0.DocTotal, T0.GrosProfit, T4.SlpName,T5.WTCODE,t5.U_Ret_ML
Alternative way :
SELECT inv.InvoiceNumber,inv.Total,[ARV1],[ARV2],[ARV3],[ICA1],[ICA2],[ICA3]
FROM INVOICE inv
JOIN(
SELECT id,[ARV1],[ARV2],[ARV3],[ICA1],[ICA2],[ICA3]
FROM
(SELECT * FROM HoldingTaxes ) t1
PIVOT(SUM(HoldedAmount) for HoldingTaxCode in
([ARV1],[ARV2],[ARV3],[ICA1],[ICA2],[ICA3])) t2
) ht
ON inv.id =ht.id
sql fiddle :http://sqlfiddle.com/#!3/ea3a4/10
I would use PIVOT to solve this - as demonstrated in the SQL Fiddle:
SELECT EmpName
,CASE WHEN ARV1 > 0 THEN 'PERRO1' ELSE NULL END
,CASE WHEN ARV2 > 0 THEN 'PERRO2' ELSE NULL END
,CASE WHEN ICA1 > 0 THEN 'PERRO3' ELSE NULL END
FROM (SELECT t0.EmpName, t1.Name, t1.Value
FROM Table0 t0 INNER JOIN Table1 t1 ON t0.Id = t1.Id ) as src
PIVOT (
MAX(src.Value)
FOR src.Name IN ([ARV1],[ARV2],[ICA1])) as p
http://sqlfiddle.com/#!3/a6ff0/2
If your having issues and willing to share your structure, I can put this into a a closer match to what you are using on SQL Fiddle.
Edit:
Based on the update you gave, here is the fiddle I created with the pivot.
http://sqlfiddle.com/#!3/47511/4
SELECT * FROM
(SELECT InvoiceNumber = Invoice.InvoiceNumber
,Total = Invoice.Total
,HoldingTaxCode = HoldingTaxes.HoldingTaxCode
,HoldedAmount = HoldingTaxes.HoldedAmount
FROM Invoice
LEFT JOIN HoldingTaxes
ON Invoice.Id = HoldingTaxes.Id) PivotSource
PIVOT
(
SUM(HoldedAmount) FOR HoldingTaxCode IN(ARV1, ARV2, ARV3, ICA1, ICA2, ICA3)
) PivotData
ORDER BY InvoiceNumber
The two CASE expressions employ the same logic. Only the value in t5.WTCode is different. Since that column is unlikely to have the value ARV1 and ICA1 at the same time you'll always get a NULL in at least one of the computed columns in any row.
You are putting different case statements for 2 different values. Therefore for each row one of them would be valid and other one null, which is what you are getting.
This is how i resolved my issue, thanks to everyone for the help
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(t5.WTCode)
FROM INV5 T5
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Factura, Fecha, SN, TotalFacturaSinImpuesto, Total$Descuento, Total$Impuesto, Total$Retenciones, Total$Factura, CostoTotal$Factura, Margen$Factura, Costo$PromedioInventario, Margen$Inventario, NombreVendedor, ' + #cols + ' from
(
select T0.DocNum [Factura], T0.DocDate [Fecha], T0.CardName [SN],SUM(T1.LineTotal) [TotalFacturaSinImpuesto], T0.DiscSum [Total$Descuento], T0.VatSum [Total$Impuesto],(T0.WTSum*-1) [Total$Retenciones],t5.WTCode [CodigoRetencion],t5.U_Ret_ML [CantidadRetenida],T0.DocTotal [Total$Factura],SUM(T1.GrossBuyPr*T1.Quantity) [CostoTotal$Factura], T0.GrosProfit [Margen$Factura],SUM(T1.Quantity*T3.AvgPrice) [Costo$PromedioInventario],(SUM(T1.LineTotal*T1.Quantity))-(SUM(T1.Quantity*T3.AvgPrice)) [Margen$Inventario], T4.SlpName [NombreVendedor]
FROM OINV T0
INNER JOIN INV1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN OSLP T4 ON T0.SlpCode = T4.SlpCode
INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode
INNER JOIN OITW T3 ON T2.ItemCode = T3.ItemCode
INNER JOIN INV5 T5 ON T5.AbsEntry = T0.DocEntry
WHERE T1.WhsCode = T3.WhsCode
GROUP BY T0.DocNum,T0.DocDate, T0.CardName,T0.BaseAmnt, T0.DiscSum, T0.VatSum, T0.WTSum,T0.DocTotal, T0.GrosProfit, T4.SlpName,T5.WTCODE,T5.U_RET_ML
) x
pivot
(
sum(CantidadRetenida)
for CodigoRetencion in (' + #cols + ')
) p '
execute(#query)

MYSQL IN substitute

Good day
I am trying to query the names of employees who work on every project.
My code is as follows:
SELECT CONCAT (fname,' ', minit,'. ' , lname) AS NAME
FROM employee a, works_on b, project c
WHERE pno IN (Select pnumber //WHAT COULD I SUBSTITUTE W/ IN
FROM projet)
AND a.ssn = b.essn
AND b.pno = c.pnumber
The problem with IN is that it is that the values inside are like evaluated as 'OR'... what is the equivalent of IN that makes the value of my subquery evaluated like 'AND'
Thank you in advance.
EDIT:
As reqeusted..
SELECT *
FROM employee e
WHERE NOT EXISTS
(
SELECT NULL
FROM employee ei
CROSS JOIN
project p
LEFT JOIN
works_on wo
ON wo.pno = p.pnumber
AND wo.essn = ei.ssn
WHERE ei.ssn = e.ssn
)
select CONCAT (fname,' ', minit,'. ' , lname) AS NAME
from employee
left join works_on
on works_on.essn=employee.ssn
group by employee.ssn
having count(works_on.essn) = (select count(*) from project);
Simplified example:
create table emp_work_on
(
emp_name varchar(50),
work_on varchar(30)
);
create table works
(
work_on varchar(30)
);
insert into works(work_on) values('apple'),('microsoft'),('google'),('facebook')
insert into emp_work_on values
('john','apple'),('john','microsoft'),('john','google'),('john','facebook'),
('paul','microsoft'),('paul','google'),
('george','apple'),('george','microsoft'),('george','google'),('george','facebook'),
('ringo','apple'),('ringo','facebook');
select e.emp_name
from works w
left join emp_work_on e on e.work_on = w.work_on
group by e.emp_name
having count(e.work_on) = (select count(*) from works)
order by e.emp_name
Output:
emp_name
----------
george
john
(2 rows)
On your table structure, you could use this:
SELECT * FROM employee
WHERE ssn IN
(
SELECT w.essn
FROM project c
LEFT JOIN works_on w ON w.pno = c.pnumber
GROUP BY w.essn
HAVING COUNT(w.pno) = (SELECT COUNT(*) FROM project)
)
Hmm.. but I think this could be the simplest, granting there's no repeating pno on employee's works_on, i.e. there's no pno in works_on that doesn't exists on project, i.e. referential integrity is maintained
SELECT * FROM employee
WHERE ssn IN
(
SELECT essn
FROM works_on
GROUP BY essn
HAVING COUNT(pno) = (SELECT COUNT(*) FROM project)
)