MYSQL Query - joining tables and grouping results - mysql

I'm after some help with a report I'm designing please.
My report includes results from a booking database where I'd like to show each booking on a single line. However as the booking database has a number of tables my MYSQL query involves JOINS which is resulting in multiple rows per booking. It is the multiple results for "dcea4_eb_field_values.field_value" per booking causing the repeating rows.
This is my query
SELECT
dcea4_eb_events.event_date,
dcea4_eb_events.title,
dcea4_eb_registrants.id,
dcea4_eb_registrants.first_name,
dcea4_eb_registrants.last_name,
dcea4_eb_registrants.email,
dcea4_eb_registrants.register_date,
dcea4_eb_registrants.amount,
dcea4_eb_registrants.comment,
dcea4_eb_field_values.field_id,
dcea4_eb_field_values.field_value
FROM dcea4_eb_events
INNER JOIN dcea4_eb_registrants ON dcea4_eb_registrants.event_id = dcea4_eb_events.id
INNER JOIN dcea4_eb_field_values ON dcea4_eb_field_values.registrant_id = dcea4_eb_registrants.id
WHERE 1=1
AND (dcea4_eb_field_values.field_id = 14 OR dcea4_eb_field_values.field_id = 26 OR dcea4_eb_field_values.field_id = 27 OR dcea4_eb_field_values.field_id = 15)
AND dcea4_eb_registrants.published <> 2
AND dcea4_eb_registrants.published IS NOT NULL
AND (dcea4_eb_registrants.published = 1 OR dcea4_eb_registrants.payment_method = "os_offline")
[ AND (dcea4_eb_registrants.register_date {RegistrationDate} ) ]
[ AND REPLACE(dcea4_eb_events.title,'\'','') in ({Club}) ]
ORDER BY dcea4_eb_registrants.register_date,
dcea4_eb_events.title
This is what the output currently looks like
current result
and this is what I'd like it to look like
desired result
Any help appreciated

Related

Mysql filter by multiply ids

I can't finish writing query to filter row by multiply ids. Here is query:
select distinct `storage_file`.*, `storage_tag`.`id` as `tid` from `storage_file`
inner join `storage_file_tag` on `storage_file`.`id` = `storage_file_tag`.`storage_file_id`
inner join `storage_tag` on `storage_tag`.`id` = `storage_file_tag`.`storage_tag_id`
where `storage_file`.`user_id` = 17 and `storage_file`.`deleted_at` is null and
`storage_tag`.`id` IN(13,17);
So the result is without group by statement is:
So.. I need result only with two records which contain tid 13 and 17
And when i replace "IN(13,17)" with storage_tag.id = 13 AND storage_tag.id = 17 - i get no records at all
How can i write subquery which will work like a + b but not a OR b ?
I'm not sure what you do exactly but it seams, that the distinct is not working as you expect, because you select "*" from storage_file, as there are different values in the columns of storage_file, the result is distincted but over all selected columnns and so more the two are selected.
You can replace
... AND id IN (11,22)
with
... AND ( id = 11 OR id = 12)
You need the parentheses because WHERE operator precedence rules are very simple.
Of course,
... AND id = 11 AND id = 12
never returns anything because the id cannot have two different values at the same time.

Mysql: I want to compare the results of two queries and return the results

In MS Access I have the following query and I want to duplicate it in MysQl
SELECT New_Date_Sev54.*
FROM New_Date_Sev54 LEFT JOIN Old_Date_Sev54 ON New_Date_Sev54.[Expr1] = Old_Date_Sev54.[Expr1]
WHERE (((Old_Date_Sev54.Expr1) Is Null));
New_date query :
SELECT perimeter.*, perimeter.IP, perimeter.QID, perimeter.Severity, [IP] & [QID] AS Expr1
FROM perimeter
WHERE (((perimeter.QID)<>38628 And (perimeter.QID)<>38675) AND ((perimeter.Severity)=5) AND ((perimeter.Date)=22118)) OR (((perimeter.Severity)=4));
Old Date Query:
SELECT perimeter.*, perimeter.IP, perimeter.QID, perimeter.Severity, [IP] & [QID] AS Expr1
FROM perimeter
WHERE (((perimeter.QID)<>38628 And (perimeter.QID)<>38675) AND ((perimeter.Severity)=5) AND ((perimeter.Date)=21918)) OR (((perimeter.Severity)=4));
In the ACCESS query, I basically take all the results with the new date and compare them against the results of the old date (week prior) and return anything that did not exist the week prior.
The database is used to quickly identify new vulnerabilities that exist in the perimeter. And is shaped like this
Date | IP| VulnID | VulnName | Severity | Threat | Resolution
What I have been trying in mysql is using the "NOT IN" comparison of two select statements. However, it is not working.
I want to know all the new vulnerabilities that have a severity of 4 or 5 and that do not have the Vuln id of 32628
Thanks
Put each query into temp tables:
CREATE TEMPORARY TABLE newVulns AS ([new date query])
CREATE TEMPORARY TABLE oldVulns AS ([old date query])
where [new date query] and [old date query] are your select statements.
Then
SELECT * FROM newVulns n
LEFT JOIN oldVulns o
ON n.VulnID = o.VulnID
WHERE o.VulnID IS NULL
AND n.VulnID != 32628
AND n.Severity NOT IN (4, 5)
I believe that should do it.
Temp table creation info found in the manual and a neat visual representation of joins can be found here. I find myself looking at those all the time.

Update With Inner Join Running Too Slow

Can somebody help optimizing the query below. The tr_marketshare table contains just 84000 records and query is taking 6 minutes and 19 seconds to execute.
UPDATE tr_marketshare
INNER JOIN
(SELECT YEAR, MONTH, Door, Category, Category_Sales,Country
FROM tr_marketshare
WHERE Brand = 'Gucci'
AND Account = 'Wojooh'
AND Category='MU') MS
ON tr_marketshare.Door = MS.Door
AND tr_marketshare.Year = MS.Year
AND tr_marketshare.Month = MS.Month
AND tr_marketshare.Account='Wojooh'
AND tr_marketshare.Country = MS.Country
AND tr_marketshare.Category = 'MU'
AND tr_marketshare.Brand <> 'Gucci'
SET tr_marketshare.Category_Sales = MS.Category_Sales;
The schema information is as below.
ID and Year are Integer.
Category_Sales is float
Rest of the fields are of Varchar type.
Thanks.

SQL Statement running extreamly Slow

Okay I have look through several posts about SQL running slow and I didn't see anything similar to this, so my apologies if I missed one. I was asked about a month ago to create a view that would allow the user to report what hasn't been billed yet, and the SQL is joining 4 tables together. One is 1.2 million records ish. the rest are between 80K - 250K. (Please note that this should only return around 100 records after the where statements).
SELECT C.Cltnum + '.' + C.CltEng AS [ClientNum],
C.CPPLname,
w.WSCDesc,
MIN(w.Wdate) AS [FirstTDate],
w.WCodeCat,
w.WCodeSub,
SUM(w.Wbilled) AS [Billed],
SUM(w.Whours * w.Wrate) AS [Billable Wip],
sum(ar.[ARProgress]) AS [Progress],
w.Winvnum,
-- dbo.GetInvoiceAmount(w.Winvnum) AS [InvoiceAmount],
SUM(cb.cinvar) AS [AR Balance]
FROM dbo.WIP AS w
--Never join on a select statement
--join BillingAuditCatagoriesT bac on w.WCodeCat = bac.Catagory and w.WCodeSub = bac.Subcatagory
INNER JOIN dbo.Clients AS C ON w.WCltID = C.ID
JOIN dbo.ClientBuckets AS cb on c.cltnum = cb.cltnum
JOIN dbo.AcctsRec AS ar on ar.arapplyto = w.[Winvnum]
-- WHERE w.wcodecat = '1AUDT'
GROUP BY C.Cltnum, C.CltEng, C.CPPLname, w.WCodeCat, w.Wdate, w.Winvnum, w.WCodeSub, w.WSCDesc
so, where I think there may be a problem is that Category is a varchar it is xat, ACT, BID and there are about 15 different Category. this is the same as SubCat. you will notice that there are 3 functions on this and they are GetJamesProgress Which is = (SELECT sum(Amount) From Progress Where inv = w.invnum) and the same with GetInvoiceAmount and GetJamesARBalance. I know that this is bad to do but when I join by invoice number it takes even longer than with out them.
Please help thanks so much!

SQL SUM issues with joins

I got a quite complex query (at least for me).
I want to create a list of users that are ready to be paid. There are 2 conditions that need to be met: order status should be 3 and the total should be more then 50. Currently I got this query (generated with Codeingiter active record):
SELECT `services_payments`.`consultant_id`
, `consultant_userdata`.`iban`
, `consultant_userdata`.`kvk`, `consultant_userdata`.`bic`
, `consultant_userdata`.`bankname`
, SUM(`services_payments`.`amount`) AS amount
FROM (`services_payments`)
JOIN `consultant_userdata`
ON `consultant_userdata`.`user_id` = `services_payments`.`consultant_id`
JOIN `services`
ON `services`.`id` = `services_payments`.`service_id`
WHERE `services`.`status` = 3
AND `services_payments`.`paid` = 0
HAVING `amount` > 50
The services_payments table contains the commissions, consultant_userdata contains the userdata and services keeps the order data. The current query only gives me 1 result while I'm expecting 4 results.
Could someone please tell me what I'm doing wrong and what would be the solution?
For ActiveRecord, rsanchez' answer would be more of
$this->db->group_by('services_payments.consultant_id, consultant_userdata.iban, consultant_userdata.kvk, consultant_userdata.bic, consultant_userdata.bankname');