MySQL Row Count on a long query - mysql

i'm trying to get out a COUNT() from the result of this query:
SELECT COUNT
(SELECT *
FROM `products` AS P
INNER JOIN `aste` AS A ON P.id_asta = A.id_asta
INNER JOIN aste_i18n AS B ON A.id_asta = B.id_asta
WHERE id_fallimento = 284
AND B.lang = 'it_IT')
How can i do this?
Thanks
Marco

Use the result of your query as a derived table and perform a COUNT operation on it:
SELECT COUNT(*)
FROM (SELECT P.id_asta
FROM `products` AS P
INNER JOIN `aste` AS A ON P.id_asta = A.id_asta
INNER JOIN aste_i18n AS B ON A.id_asta = B.id_asta
WHERE id_fallimento = 284 AND B.lang = 'it_IT') AS t

Related

MySQL Subquery Optimization with shared subquery

From these tables I have written this subquery and its giving results as per requirements.
Needs expert guidence to improve this query or if we can also be able to use join for these tables.
Query:
select ps,st from pac where con in (select
config from config where logi in
( select id from logicalnode where physi
in (select id from ysicalnode where mas =11)));
SELECT
payloadstr
,starttime
FROM packetdb.packet
INNER JOIN packetdb.configuration
ON packetdb.packet.configid = packetdb.configuration.idconfig
INNER JOIN packetdb.logicalnode
ON packetdb.configuration.idconfig = packetdb.logicalnode.id
INNER JOIN packetdb.physicalnode
ON packetdb.logicalnode.physicalnodeid = packetdb.physicalnode.id and packetdb.physicalnode.macaddress=117769729
You could try using exists:
select payloadstr,starttime from packetdb.packet p
where exists(select 1 from packetdb.configuration c
where p.configid = id
and exists(select 1 from packetdb.logicalnode l
where c.logicalnodeid = id
and exists(select 1 from packetdb.physicalnode
where macaddress = 117769729
and l.physicalnodeid = id)
Using Left join
select payloadstr,starttime
from packet
left join Configuration on Configuration.IDconfig = packet.configID
left join logicalnode on logicalnode.ID = Configuration.logicalnodeid
left join physicalnode on physicalnode.ID = logicalnode.physicalnodeid
where macaddress =117769729
You can try below - using JOIN
select payloadstr,starttime
from packetdb.packet a inner join packetdb.configuration b on a.configid=b.idconfig
inner join packetdb.logicalnode c on logicalnodeid=c.id
inner join packetdb.physicalnode d on physicalnodeid=d.id
where macaddress =117769729
Try this
select pa,sta
from
pack p
INNER JOIN
confi c
ON
p.confi = c.idco
INNER JOIN
logice l
ON
c.logic = l.id
INNER JOIN
physiode pn
ON
l.physicalnodeid = pn.id
WHERE macaddress =123

How to efficiently select the rows corresponding with the highest value for a specific column?

I have a query:
SELECT * FROM `InvoiceLines`
INNER JOIN Invoices ON Invoices.`invoiceID` = InvoiceLines.`invoiceID`
INNER JOIN `DistributorOrdersTbl` ON DistributorOrdersTbl.`distOrderRecID` = Invoices.`orderID`
WHERE DistributorOrdersTbl.`distOrderRecID` = 3829
AND InvoiceLines.`qty` > 0
Which returns a number of Invoices:
I wanted to select only the invoices with the newest ID 2800. The way I ended up doing it was a bit of copy pasting:
SELECT * FROM `InvoiceLines`
INNER JOIN Invoices ON Invoices.`invoiceID` = InvoiceLines.`invoiceID`
INNER JOIN `DistributorOrdersTbl` ON DistributorOrdersTbl.`distOrderRecID` = Invoices.`orderID`
WHERE DistributorOrdersTbl.`distOrderRecID` = 3829
AND InvoiceLines.`qty` > 0
AND Invoices.invoiceID = (
SELECT MAX(Invoices.invoiceID) FROM `InvoiceLines`
INNER JOIN Invoices ON Invoices.`invoiceID` = InvoiceLines.`invoiceID`
INNER JOIN `DistributorOrdersTbl` ON DistributorOrdersTbl.`distOrderRecID` = Invoices.`orderID`
WHERE DistributorOrdersTbl.`distOrderRecID` = 3829
AND InvoiceLines.`qty` > 0
)
And sure enough, the correct invoices are returned. However it feels as though this is inefficient as I am essentially performing the query twice. What would be the best way of doing this? I tried the following but it seems this is incorrect SQL:
SELECT * FROM `InvoiceLines`
INNER JOIN Invoices ON Invoices.`invoiceID` = InvoiceLines.`invoiceID`
INNER JOIN `DistributorOrdersTbl` ON DistributorOrdersTbl.`distOrderRecID` = Invoices.`orderID`
WHERE DistributorOrdersTbl.`distOrderRecID` = 3829
AND InvoiceLines.`qty` > 0
AND Invoices.invoiceID = MAX(Invoices.invoiceID)
Which returns "Invalid use of group function".
Thanks in advance!
Assuming all invoices have invoice lines, you can use a subquery just on Invoices:
SELECT *
FROM (SELECT i.*
FROM Invoices i
WHERE i.orderID = 3829
ORDER BY i.invoiceID DESC
LIMIT 1
) i JOIN
InvoiceLines il
ON i.invoiceID = il.invoiceID JOIN
DistributorOrdersTbl d
ON d.distOrderRecID = i.orderID
WHERE il.qty > 0;

mysql inner join return null value,

SELECT `mpeda_fish`.`id`, `mpeda_fish`.`fish` as analysis, sum(mpeda_fishdetails.quantity) as qty
FROM (`mpeda_fishdetails`)
INNER JOIN `mpeda_scientificfish` ON `mpeda_scientificfish`.`id` = `mpeda_fishdetails`.`scientificfish`
INNER JOIN `mpeda_fish` ON `mpeda_fish`.`id` = `mpeda_scientificfish`.`fish`
INNER JOIN `mpeda_fishcatch` ON `mpeda_fishcatch`.`id` = `mpeda_fishdetails`.`fishcatch`
INNER JOIN `mpeda_harbour` ON `mpeda_harbour`.`id` = `mpeda_fishcatch`.`harbour`
WHERE `mpeda_fishcatch`.`status` = 1
ORDER BY `mpeda_fishdetails`.`id` ASC
this query gets 2 columns null value and one column gets data inside why?
You use the SUM() function. In order to get meaningful results you should have a group by clause.
SELECT `mpeda_fish`.`id`, `mpeda_fish`.`fish` as analysis, sum(mpeda_fishdetails.quantity) as qty
FROM (`mpeda_fishdetails`)
INNER JOIN `mpeda_scientificfish` ON `mpeda_scientificfish`.`id` = `mpeda_fishdetails`.`scientificfish`
INNER JOIN `mpeda_fish` ON `mpeda_fish`.`id` = `mpeda_scientificfish`.`fish`
INNER JOIN `mpeda_fishcatch` ON `mpeda_fishcatch`.`id` = `mpeda_fishdetails`.`fishcatch`
INNER JOIN `mpeda_harbour` ON `mpeda_harbour`.`id` = `mpeda_fishcatch`.`harbour`
WHERE `mpeda_fishcatch`.`status` = 1
GROUP BY `mpeda_fish`.`id`, `mpeda_fish`.`fish`
ORDER BY `mpeda_fishdetails`.`id` ASC

SQL JOIN Query - linking four tables

I have the SQL to display ALL the activities and relative Admin permissions (if any) for that activity.
Current SQL Code:
SELECT `activities`.*, `admins`.`admin_role_id`
FROM (`activities`)
LEFT JOIN `admins` ON `admins`.`activity_id`=`activities`.`id` AND admins.member_id=27500
WHERE `activities`.`active` = 1
Returning:
id | name | description | active | admin_role_id (or null)
I then need to detect whether they are an active member within that Activity.
I have the following SQL code:
SELECT DISTINCT `products`.`activity_ID` as joinedID
FROM (`transactions_items`)
JOIN `transactions` ON `transactions`.`id` = `transactions_items`.`id`
JOIN `products` ON `products`.`id` = `transactions_items`.`product_id`
JOIN `activities` ON `activities`.`id` = `products`.`activity_ID`
WHERE `transactions`.`member_id` = 27500
AND `activities`.`active` = 1
Is there any way to merge this into one SQL query. I can't figure out how to use the correct JOIN queries, because of the complexity of the JOINs.
Help please, thanks! :)
Try like this
SELECT `activities`.*, `admins`.`admin_role_id`
FROM (`activities`)
LEFT JOIN `admins` ON `admins`.`activity_id`=`activities`.`id` AND admins.member_id=27500
JOIN (`transactions_items`
JOIN `transactions` ON `transactions`.`id` = `transactions_items`.`id`
JOIN `products` ON `products`.`id` = `transactions_items`.`product_id`)
ON `activities`.`id`=`products`.`activity_ID`
WHERE `transactions`.`member_id` = 27500
AND `activities`.`active` = 1
Seems to me that a query like this would be marginally more comprehensible and (I think) adhere more closely to the spec...
SELECT c.*
, d.admin_role_id
FROM activities c
LEFT
JOIN admins d
ON d.activity_id = c.id
AND d.member_id = 27500
LEFT
JOIN products p
ON p.activity_ID = c.id
LEFT
JOIN transactions_items ti
ON ti.product_id = p.id
LEFT
JOIN transactions t
ON t.id = ti.id
AND t.member_id = 27500
WHERE c.active = 1

Getting the latest date from a id

I run the above sql statement and i got this.[IMG]http://i1093.photobucket.com/albums/i422/walkgirl_1993/asd-1_zps5506632e.jpg[/IMG] i'm trying display the latest date which you can see the 3 and 4. For caseid 3, it should display the latest row which is the 2012-12-20 16:12:36.000. I tried using group by, order by. Google some website said to use rank but i'm not sure about the rank as i dont really get rank. Some suggestions?
select [Case].CaseID, Agent.AgentName, Assignment.Description, A.AgentName as EditedBy, A.DateEdited from Agent inner join [Case-Agent] on [Case-Agent].AgentID = Agent.AgentID inner join [Assignment] on Assignment.AssignmentID = [Case-Agent].AssignmentID inner join [Case] on [Case].CaseID = [Case-Agent].CaseID inner join (select EditedCase.CaseID, [EditedCase].DateEdited, [Agent].AgentName from EditedCase inner join [Agent] on [Agent].AgentID = [EditedCase].AgentID) A on A.CaseID = [Case].CaseID where [Assignment].AssignmentID = 0
To do it using RANK you just need to add the RANK to the subquery and get to rank the DateEdited for each CaseID and Agent and then in the main query put a WHERE clause to only select rows where the rank is 1. I think I have got the partition clause right - its a bit hard without seeing your data.
Like this:
SELECT
[Case].CaseID
,Agent.AgentName
,Assignment.Description
,A.AgentName AS EditedBy
,A.DateEdited
FROM Agent
INNER JOIN [Case-Agent] ON [Case-Agent].AgentID = Agent.AgentID
INNER JOIN [Assignment] ON Assignment.AssignmentID = [Case-Agent].AssignmentID
INNER JOIN [Case] ON [Case].CaseID = [Case-Agent].CaseID
INNER JOIN (SELECT
EditedCase.CaseID
,[EditedCase].DateEdited
,[Agent].AgentName
,RANK ( ) OVER (PARTITION BY EditedCase.CaseID, [Agent].AgentName
ORDER BY [EditedCase].DateEdited DESC ) AS pos
FROM EditedCase
INNER JOIN [Agent] on [Agent].AgentID = [EditedCase].AgentID) A on A.CaseID = [Case].CaseID
WHERE [Assignment].AssignmentID = 0
AND pos = 1
You could also change the sub query into an aggregate query that brings back the MAX date like this:
SELECT
[Case].CaseID
,Agent.AgentName
,Assignment.Description
,A.AgentName AS EditedBy
,A.DateEdited
FROM Agent
INNER JOIN [Case-Agent] ON [Case-Agent].AgentID = Agent.AgentID
INNER JOIN [Assignment] ON Assignment.AssignmentID = [Case-Agent].AssignmentID
INNER JOIN [Case] ON [Case].CaseID = [Case-Agent].CaseID
INNER JOIN (SELECT
EditedCase.CaseID
,MAX([EditedCase].DateEdited) AS DateEdited
,[Agent].AgentName
FROM EditedCase
INNER JOIN [Agent] on [Agent].AgentID = [EditedCase].AgentID
GROUP BY
EditedCase.CaseID
,[Agent].AgentName) A on A.CaseID = [Case].CaseID
WHERE [Assignment].AssignmentID = 0
AND pos = 1
You were on the right track; you need to use a ranking function here, for example row_number():
with LatestCase as
(
select [Case].CaseID
, Agent.AgentName
, Assignment.Description
, A.AgentName as EditedBy
, A.DateEdited
, caseRank = row_number() over (partition by [Case].CaseID order by A.DateEdited desc)
from Agent
inner join [Case-Agent] on [Case-Agent].AgentID = Agent.AgentID
inner join [Assignment] on Assignment.AssignmentID = [Case-Agent].AssignmentID
inner join [Case] on [Case].CaseID = [Case-Agent].CaseID
inner join
(
select EditedCase.CaseID
, [EditedCase].DateEdited
, [Agent].AgentName
from EditedCase
inner join [Agent] on [Agent].AgentID = [EditedCase].AgentID
) A on A.CaseID = [Case].CaseID where [Assignment].AssignmentID = 0
)
select *
from LatestCase
where caseRank = 1