I want to join three tables respectively from the below SQLFiddle
http://sqlfiddle.com/#!9/5dd558/4
Now I want to create one table from this table based on date and Brand.
Like, I want data in this manner
Date, Brand, Series, Table_1_Viewers, Table_2_Viewers, Table_2_Viewers
and if data is not matched on the table then the field should be nulled.
What I have done
SELECT h.*,
a.`amazon_viewers` AS "Table_1_Viewers",
n.`views` AS "Table_2_Viewers",
FROM `Table-1` h
LEFT JOIN `Table-2` a
ON h.`date` = a.`date`
AND h.`brand` = a.`brand`
LEFT JOIN `Table-3` n
ON h.`date` = n.`date`
AND h.`brand` = n.`brand`
Obviously I am selecting data from table-1 so it will display brand column only from table-1 but how can I get all table's brand column name in one column and merge these tables.??
The output I want...
| Date | Brand | Series | Table_1_Viewers | Table_2_Viewers | Table_3_Viewers |
|:----------:|:--------:|:--------------:|:---------------:|:---------------:|:---------------:|
| 12/1/2018 | TEST | TEST_SERIES | 100 | | |
| 10/15/2018 | MTV | GOT | 1000 | | 1000 |
| 12/1/2018 | TEST | Viking | 485632 | 856325 | |
| 12/1/2018 | TEST | Another Series | | 200 | |
| 10/15/2018 | POGO | GOT | | 1000 | |
| 7/1/2019 | No_Match | TEST_SERIES | | | 100 |
| 12/1/2018 | TEST-5 | Viking | | | 953022 |
You can do union all with aggregation :
select t.Date, t.Brand, t.Series_name,
sum(case when table_view = 't1' then amazone_viewer else 0 end) as Table_1_Viewers,
. . .
from (select h.date, h.brand, h.series_name, h.amazone_viewer, 't1' as table_view
from `Table-1` h union all
select h1.date, h1.brand, h1.series, h1.viewes, 't2'
from `Table-2` h1 union all
. . .
) t
group by t.Date, t.Brand, t.Series_name;
Related
I am struggling to find a way to get a GRAND TOTAL count of the number of rows matched in a LEFT JOIN.
This is the current query:
SELECT * FROM renewal
LEFT JOIN appointment ON appointment.renewalid=renewal.id
I have tried:
SELECT *, COUNT(app.id) AS appcount FROM renewal
LEFT JOIN appointment ON appointment.renewalid=renewal.id
But that is obviously not the right way, as it only returns the total appointments for each renewal row returned.
I have also tried a subquery:
SELECT customer.*, app.totalcount FROM renewal
LEFT JOIN (SELECT COUNT(id) AS appcount FROM appointment) AS app ON app.renewalid=renewal.id
This also is not working.
Currently, I can get it to return the total for each customer, but not a GRAND TOTAL.
The reason I am not just querying the appointments table alone, is because I need it only to return a grand total of appointments linked to customers which follow the specified OUTER 'WHERE' statement.
Disclaimer: The queries above are a much more simplified version, just for readability sakes.
Here is the full query:
SELECT
renewal.id AS renid,
renewal.personid,
renewal.enddate,
renewal.assettype,
renewal.producttype,
renewal.vrm,
renewal.make,
renewal.model,
renewal.submodel,
renewal.derivative,
renewal.complete,
person.forename,
person.surname,
person.company,
appointment.id AS appid,
COUNT(appointment.renewalid) AS appointedcount,
appointment.renewalid,
n.latestnote,
(
SELECT
COUNT(complete)
FROM
renewal
WHERE
complete = 1 && enddate BETWEEN '2020-01-01' AND '2020-01-30' && dealershipid = '1' && assettype = 'N' && producttype NOT LIKE '%CH%' && complete = 1
) AS renewedcount
FROM
renewal
LEFT JOIN person ON person.id = renewal.personid
LEFT JOIN appointment ON appointment.renewalid = renewal.id
LEFT JOIN(
SELECT
note AS latestnote,
TIMESTAMP,
renewalid
FROM
renewal_note
ORDER BY
TIMESTAMP
DESC
) AS n
ON
n.renewalid = renewal.id
WHERE
enddate BETWEEN '2020-01-01' AND '2020-01-30' && renewal.dealershipid = '1' && assettype = 'N' && producttype NOT LIKE '%CH%'
GROUP BY
renid
ORDER BY
enddate ASC
This is what is being outputted with the Full query (Removed cluttering columns which arent relevant to this question):
| renid | appid | appointedcount | renewedcount | |
|--------|--------|-----------------|---------------|--|
| 60177 | 1096 | 6 | 5 | |
| 64704 | 2470 | 6 | 5 | |
| 43057 | | 0 | 5 | |
| 64626 | | 0 | 5 | |
| 11123 | | 0 | 5 | |
| 72469 | | 0 | 5 | |
| 76055 | 2879 | 7 | 5 | |
| 76001 | 2546 | 3 | 5 | |
| 72171 | 2769 | 6 | 5 | |
| 76073 | | 0 | 5 | |
| 73183 | 2093 | 8 | 5 | |
| 73114 | 2834 | 6 | 5 | |
| 43088 | | 0 | 5 | |
| 732 | | 0 | 5 | |
| 11157 | | 0 | 5 | |
| 60207 | | 0 | 5 | |
| 73103 | 2015 | 3 | 5 | |
| 75982 | | 0 | 5 | |
| 43076 | | 0 | 5 | |
It seems like the highest appointedcount value is 8, which if you count the number of rows with an appid (an appointment), adds up to 8.
I believe I am heading in the right direction, as it is returning 8 (at a random renewal row), but can't seem to get past this point.
Can someone please guide me in the right direction?
I think you want a window function:
SELECT *, COUNT(a.id) OVER () AS total_appcount
FROM renewal r LEFT JOIN
appointment a
ON a.renewalid = r.id ;
In older versions of MySQL, you can use a correlated subquery:
SELECT *,
(SELECT COUNT(*)
FROM renewal r JOIN
appointment a
ON a.renewalid = r.id
) AS total_appcount
FROM renewal r LEFT JOIN
appointment a
ON a.renewalid = r.id ;
Note that for the subquery, you don't need an outer join, because you only want matches.
I have two queries that pull data from two different tables, but I need them to pull in the same report. I have a shared key between them, and the first table has one entry that corresponds to many entries in the second table.
My first query:
SELECT Proposal_ID,
substr(Proposal_Name, 1, 3) AS Prefix,
substr(Proposal_Name, 4, 6) AS `Number`,
Institution,
CollegeCode,
DepartmentCode,
Proposer_FirstName,
Proposer_LastName
FROM proposals.proposal
WHERE Institution = 'T';
Sample Data:
+----+--------+--------+-------+----------+----------+-----------+----------+
| ID | Prefix | Number | Inst. | CollCode | DeptCode | FirstName | LastName |
+----+--------+--------+-------+----------+----------+-----------+----------+
| 18 | SYP | 4675 | T | AS | SOC | Linda | McGaff |
+----+--------+--------+-------+----------+----------+-----------+----------+
| 20 | GEO | 4340 | T | AS | SGS | Teddy | Graham |
+----+--------+--------+-------+----------+----------+-----------+----------+
My second query:
SELECT Parent_Proposal,
SUBSTRING_INDEX(GROUP_CONCAT(`status`.`Status_Code` ORDER BY `status`.`Status_Time` DESC), ',', 1) AS status_code,
SUBSTRING_INDEX(GROUP_CONCAT(`status`.`Status_Time` ORDER BY `status`.`Status_Time` DESC), ',', 1) AS status_timestamp
FROM proposals.`status`
GROUP BY `status`.Parent_Proposal
Sample Data:
+-----------------+-------------+----------------------+
| Parent_Proposal | Status_Code | Status_Time |
+-----------------+-------------+----------------------+
| 18 | 40 | 2016-11-09 06:30:35 |
+-----------------+-------------+----------------------+
| 20 | 11 | 2017-03-20 10:26:31 |
+-----------------+-------------+----------------------+
I basically need to pull the most recent Status_Code and Status_Timestamp based on the Status_Timestamp and then relate that to the first table with the Parent_Proposal column.
Is there a way to group a subset of results without grouping all of the data together?
Expected Result:
+----+--------+--------+-------+----------+----------+-------+--------+-------------+----------------------+
| ID | Prefix | Number | Inst. | CollCode | DeptCode | FName | LName | Status_Code | Status_Time |
+----+--------+--------+-------+----------+----------+-------+--------+-------------+----------------------+
| 18 | SYP | 4675 | T | AS | SOC | Linda | McGaff | 40 | 2016-11-09 06:30:35 |
+----+--------+--------+-------+----------+----------+-------+--------+-------------+----------------------+
| 20 | 11 | GEO | 4340 | AS | SGS | Teddy | Graham | 11 | 2017-03-20 10:26:31 |
+----+--------+--------+-------+----------+----------+-------+--------+-------------+----------------------+
Thanks for any help and insight!
I think you want this. Just join your two tables together, and then do an additional join to a subquery on the status table to find the latest record for each parent proposal.
SELECT
p.Proposal_ID,
SUBSTR(p.Proposal_Name, 1, 3) AS Prefix,
SUBSTR(p.Proposal_Name, 4, 6) AS Number,
p.Institution,
p.CollegeCode,
p.DepartmentCode,
p.Proposer_FirstName,
p.Proposer_LastName,
s1.Status_Code,
s1.Status_Time
FROM proposals.proposal p
LEFT JOIN proposals.status s1
ON p.ID = s1.Parent_Proposal
INNER JOIN
(
SELECT Parent_Proposal, MAX(Status_Time) AS Max_Status_Time
FROM proposals.status
GROUP BY Parent_Proposal
) s2
ON s1.Parent_Proposal = s2.Parent_Proposal AND s1.Status_Time = s2.Max_Status_Time
WHERE
p.Institution = 'T';
the table structure is as follows
+---------------+----------+-------------------+-------------+---------+--------+-------------------------+----------------+----------------+-----------------------+----------------------+---------------------+-------------------+--------------+
| REDEMPTION_ID | CCID | MEMBERSHIP_NUMBER | POINTS_TYPE | PARTNER
| SCHEME | REDEMPTION_ORDER_STATUS | MEMBER_SEGMENT | PARTNER_POINTS |
MEMBERSHIP_FIRST_NAME | MEMBERSHIP_LAST_NAME | REDEMPTION_DATE |
OUTBOUND_FILENAME | PRODUCT_TYPE |
+---------------+----------+--------
-----------+-------------+---------+--------+-------------------------+----------------+----------------+-----------------------+----------------------+---------------------+-------------------+--------------+
| 1003740 | 21212103 | 1231237 | BASE | QANTAS
| Visa | ORDERED | LEGACY | 5000.000000 |
e | Name | 2017-10-23 10:26:51 |
NABQF05P.012 | CONSUMER |
| 1003741 | 21212103 |1231238 | BONUS | QANTAS | Visa | ORDERED | LEGACY | 2500.000000 | e | Name
| 2017-10-23 10:26:51 | NABQF05P.012 | CONSUMER |
I want to group the above rows based on the columns Membership_Number and POINTS_TYPE and the resulting row should be one row.
I am using the following query :
select * from ((
select * from NAB_REDEMPTION_DETAILS
where PARTNER='QANTAS' and REDEMPTION_ORDER_STATUS IN ('PLACED','RESEND') and POINTS_TYPE = 'BASE' group by MEMBERSHIP_NUMBER) a
left OUTER JOIN (
select * from NAB_REDEMPTION_DETAILS
where PARTNER='QANTAS' and REDEMPTION_ORDER_STATUS IN ('PLACED','RESEND') and POINTS_TYPE = 'BONUS' group by MEMBERSHIP_NUMBER) b on a.MEMBERSHIP_NUMBER=b.MEMBERSHIP_NUMBER) union (
select * from (
select * from NAB_REDEMPTION_DETAILS
where PARTNER='QANTAS' and REDEMPTION_ORDER_STATUS IN ('PLACED','RESEND') and POINTS_TYPE = 'BASE' group by MEMBERSHIP_NUMBER) c right OUTER JOIN (
select * from NAB_REDEMPTION_DETAILS
where PARTNER='QANTAS' and REDEMPTION_ORDER_STATUS IN ('PLACED','RESEND') and POINTS_TYPE = 'BONUS' group by MEMBERSHIP_NUMBER) d on c.MEMBERSHIP_NUMBER=d.MEMBERSHIP_NUMBER)
when executing the query I am getting the above mentioned exception
I figured it out. since I was using joins in the same table and the Redemption_id was a Primarykey, It was resulting in the exception. I used group_concat instead of join and it solved my problem.
Kindly find the solution in the link http://sqlfiddle.com/#!9/dc59a1/5
Which of the following queries style is better for performance?
Basically, I'm returning many related records into one row with GROUP_CONCAT and I need to filter by another join on the GROUP_CONCAT value, and I will need to add many more either joins/group_concats/havings or sub queries in order to filter by more related values. I saw that, officially, LEFT JOIN was faster, but I wonder if the GROUP_CONCAT and HAVING through that off.
(This is a very simplified example, the actual data has many more attributes and it's reading from a Drupal MySQL architecture)
Thanks!
Main Records
+----+-----------------+----------------+-----------+-----------+
| id | other_record_id | value | type | attribute |
+----+-----------------+----------------+-----------+-----------+
| 1 | 0 | Red Building | building | |
| 2 | 1 | ACME Plumbing | attribute | company |
| 3 | 1 | east_side | attribute | location |
| 4 | 0 | Green Building | building | |
| 5 | 4 | AJAX Heating | attribute | company |
| 6 | 4 | west_side | attribute | location |
| 7 | 0 | Blue Building | building | |
| 8 | 7 | ZZZ Mattresses | attribute | company |
| 9 | 7 | south_side | attribute | location |
+----+-----------------+----------------+-----------+-----------+
location_transaltions
+-------------+------------+
| location_id | value |
+-------------+------------+
| 1 | east_side |
| 2 | west_side |
| 3 | south_side |
+-------------+------------+
locations
+----+--------------------+
| id | name |
+----+--------------------+
| 1 | Arts District |
| 2 | Warehouse District |
| 3 | Suburb |
+----+--------------------+
Query #1
SELECT
a.id,
GROUP_CONCAT(
IF(b.attribute = 'company', b.value, NULL)
) AS company_value,
GROUP_CONCAT(
IF(b.attribute = 'location', b.value, NULL)
) AS location_value,
GROUP_CONCAT(
IF(b.attribute = 'location', lt.location_id, NULL)
) AS location_id
FROM
records a
LEFT JOIN records b ON b.other_record_id = a.id AND b.type = 'attribute'
LEFT JOIN location_translations lt ON lt.value = b.value
WHERE a.type = 'building'
GROUP BY a.id
HAVING location_id = 2
Query #2
SELECT temp.* FROM (
SELECT
a.id,
GROUP_CONCAT(
IF(b.attribute = 'company', b.value, NULL)
) AS company_value,
GROUP_CONCAT(
IF(b.attribute = 'location', b.value, NULL)
) AS location_value
FROM
records a
LEFT JOIN records b ON b.other_record_id = a.id AND b.type = 'attribute'
WHERE a.type = 'building'
GROUP BY a.id
) as temp
LEFT JOIN location_translations lt ON lt.value = temp.location_value
WHERE location_id = 2
Using JOIN is preferable in most cases, because it helps optimizer to understand which indexes he can to use. In your case, query #1 looks good enough.
Of course, it works only if tables has indexes. Check table records has indexes on id, other_record_id, value and type columns, table location_translations on value
I have a Mysql table with the following data.
|ID | Date | BillNumber|BillMonth | Amount | Name |AccNum |
| 2 |2015-09-25| 454345 | 092015 | 135.00 |Andrew Good| 735976|
| 3 |2015-09-26| 356282 | 092015 | 142.00 |Peter Pan | 123489|
| 4 |2015-08-11| 312738 | 082015 | 162.00 |Andrew Good| 735976|
| 5 |2015-07-12| 287628 | 072015 | 220.67 |Andrew Good| 735976|
| 6 |2015-06-12| 100756 | 062015 | 556.34 |Andrew Good| 735976|
What I wanted to achieve is to retrieve the data of Andrew Good with AccNum 735976 for the BillMonth of 092015, provided that the user can entry any of his BillNumber(past/current).
If the reason that that row is of interest is because it is the latest of his rows, try:
select *
from tbl t
where name = ( select name
from tbl
where billnumber = 100756 -- can be any of his
)
and date = ( select max(date)
from tbl x
where x.name = t.name
)
(the billnumber can be any of his)