SQL : How can I get count from multiple tables into one query? - mysql

I have 3 tables, one for website connection errors, one for successful website connections and another with name/location of each specific website.
Table 1 has WebsiteClass_ID, Website_ID and Error_Date
Table 2 has WebsiteClass_ID, Website_ID and Success_Date
Table 3 has WebsiteClass_ID, Website Name and Location
I need to return the rate of error by WebsiteClass_ID by Website_ID per day. To do this, I need the count of errors per WebsiteClass_ID, Website_ID and Date from Table 1 and the count of successful connections per WebsiteClass_ID, Website_ID and Date from Table 2. I still need to return Website Name and Location from table 3 as well. The date field is different in Table 1 than it is in Table 2.
I can easily get the count for each in two different queries but would prefer to accomplish this in one query to avoid extra work in Excel. I created the two individual queries below but do not know how to merge them.
#QUERY
#TITLE-WEBSEROR
#SUBJECT-WEBSITE ERRORS PER DAY BY CLASS AND ID
SELECT
A.WEBSITE_CLASS_ID AS WEBSITE_CLASS_ID
,A.WEBSITE_ID AS WEBSITE_ID
,A.ERROR_DATE AS DATE_OF_ERROR
,COUNT(A.EVENT_NAME) AS NUMBER_OF_ERRORS
,B.NAME AS WEBSITE_NAME
,B.LOCATION AS COMPANY_LOCATION
FROM
&DATABASE..ERRORS A
,&DATABASE..DETAILS B
WHERE
A.WEBSITE_ID = B.WEBSITE_ID
GROUP BY A.WEBSITE_CLASS_ID, A.WEBSITE_ID, A.ERROR_DATE, B.NAME, B.LOCATION
#QUERY
#TITLE-WEBSCNFM
#SUBJECT-SUCCESSUL CONNECTIONS PER DAY BY CLASS AND ID
SELECT
C.WEBSITE_CLASS_ID AS WEBSITE_CLASS_ID
,C.WEBSITE_ID AS WEBSITE_ID
,DATE(C.SUCCESS_DATE) AS SUCCESSFUL_CONNECTION
,COUNT(C.SUCCESS) AS COUNT_SUCCESS_CNCTN
,B.NAME AS WEBSITE_NAME
,B.LOCATION AS COMPANY_LOCATION
FROM
&DATABASE..SUCCESS C
,&DATABASE..DETAILS B
WHERE
C.WEBSITE_ID = B.WEBSITE_ID
GROUP BY C.WEBSITE_CLASS_ID, C.WEBSITE_ID, DATE(C.SUCCESS_DATE), B.NAME, B.LOCATION
Data Sample:
Table 1: Errors
Table 2: Success
Table 3: Details
Expected Results :
Website_Class_ID
Website_ID
Date of Error or Success
Count of Errors
Count of Success
Website Name
Website Location
ClassB
ID 2
12/1/2019
3
5
Website #1
USA
ClassC
ID 3
12/2/2019
1
6
Website #2
Canada
SELECT
`Errors$`.WEBSITE_CLASS_ID
,`Errors$`.WEBSITE_ID
,`Errors$`.ERROR_DATE
,COUNT(`Errors$`.EVENT_NAME)
,`Details$`.NAME
,`Details$`.LOCATION
FROM
`D:\mike\SnapCommerce Case Study\Data.xlsx`.`Errors$` `Errors$`,
INNER JOIN `D:\mike\SnapCommerce Case Study\Data.xlsx`.`Details$`
`Details$`
ON `Details$`.WEBSITE_ID = `Errors$`.WEBSITE_ID
GROUP BY `Errors$`.WEBSITE_CLASS_ID, `Errors$`.WEBSITE_ID,
`Errors$`.ERROR_DATE, `Details$`.NAME, `Details$`.LOCATION
UNION
SELECT
`Success$`.WEBSITE_CLASS_ID
,`Success$`.WEBSITE_ID
,DATE(`Success$`.SUCCESS_DATE)
,COUNT(`Success$`.SUCCESS)
,`Details$`.NAME
,`Details$`.LOCATION
FROM
`D:\mike\SnapCommerce Case Study\Data.xlsx`.`Success$` `Success$`,
INNER JOIN `D:\mike\SnapCommerce Case Study\Data.xlsx`.`Details$`
`Details$`
ON `Details$`.WEBSITE_ID = `Success$`.WEBSITE_ID
GROUP BY `Success$`.WEBSITE_CLASS_ID, `Success$`.WEBSITE_ID,
`Success$`.SUCCESS_DATE, `Details$`.NAME, `Details$`.LOCATION

Vertically, You can use UNION, this would eliminate doubles as well.
If you need them use UNION ALL
SELECT
A.WEBSITE_CLASS_ID AS WEBSITE_CLASS_ID
,A.WEBSITE_ID AS WEBSITE_ID
,A.ERROR_DATE AS DATE_OF_ERROR
,COUNT(A.EVENT_NAME) AS NUMBER_OF_ERRORS
,B.NAME AS WEBSITE_NAME
,B.LOCATION AS COMPANY_LOCATION
FROM
&DATABASE..ERRORS A
INNER JOIN &DATABASE..DETAILS B
ON A.WEBSITE_ID = B.WEBSITE_ID
GROUP BY A.WEBSITE_CLASS_ID, A.WEBSITE_ID, A.ERROR_DATE, B.NAME, B.LOCATION
UNION
SELECT
C.WEBSITE_CLASS_ID AS WEBSITE_CLASS_ID
,C.WEBSITE_ID AS WEBSITE_ID
,DATE(C.SUCCESS_DATE) AS SUCCESSFUL_CONNECTION
,COUNT(C.SUCCESS) AS COUNT_SUCCESS_CNCTN
,B.NAME AS WEBSITE_NAME
,B.LOCATION AS COMPANY_LOCATION
FROM
&DATABASE..SUCCESS C
INNER JOIN
&DATABASE..DETAILS B
ON C.WEBSITE_ID = B.WEBSITE_ID
GROUP BY C.WEBSITE_CLASS_ID, C.WEBSITE_ID, DATE(C.SUCCESS_DATE), B.NAME, B.LOCATION

Related

Set Count Values from one table to Another

I am trying to count matching values from customer column on table 'Customers' and update their values on the Count Column in table 'Summary'. I also want to Check if the Date is <= Todays Date.
Table "Customers":
ID
Customer
Date
1
John
2022-01-01
2
John
2022-01-01
3
Mary
2022-01-01
4
Mary
2022-01-01
.......+2000 More Customers
Table "Summary":
ID
Customer
Count
DateInput
1
John
2
2021-01-01
2
Mary
2
2021-01-01
.........+100 More Customers
I can update one row at a time like this:
update Summary
set Count = (SELECT COUNT(*)
FROM Customers
WHERE Customer = "John" AND Date <=CURRENT_DATE())
WHERE Customer = "John";
Is there a way to use the above query to update the count column for John, mary, etc, etc without doing Multiple individual requests?
Is this something you are looking for?
UPDATE
Summary s
INNER JOIN Customers c ON s.Customer = c.Customer
SET
s.Count = (
SELECT
COUNT(*)
FROM
Customers c2
WHERE
c2.Customer = s.Customer
AND c2.Date <= CURRENT_DATE()
)
If you are going to test the query, please test it on a small dataset before applying it to the entire table since it may not achieve the results you are expecting.
Given that your count values will change, you should consider creating a view instead of updating a table:
CREATE VIEW summary AS
SELECT ID, Customer, COALESCE(COUNT(CASE WHEN Date <= CURRENT_DATE() THEN 1 END), 0) AS cnt
FROM Customers
GROUP BY ID, Customer
If you really want to have a table and update it every time, you need such UPDATE statement:
WITH cte AS (
SELECT ID, Customer, COUNT(*) AS count
FROM Customers
WHERE Date <= CURRENT_DATE()
GROUP BY ID, Customer
)
UPDATE Summary
INNER JOIN cte ON Summary.ID = cte.ID AND Summary.Customer = cte.Customer
SET Summary.count = cte.count
You can do it as follows :
UPDATE Summary s
INNER JOIN (
SELECT Customer, count(1) as _count
FROM Customers
where Date <=CURRENT_DATE()
group by Customer
) as c on s.Customer = c.Customer
set s.Count = c._count ;
I have used inner join to join a list of customers and their counts.
and the relation is Customer.

How to get list of users that have used only one value in multiple rows - MySQL

I have a table for payments. It has a column named user_id, & payment_type. For every payment, a user can have multiple payment types.
I want to find the users that have used only one payment_type in their entire lifetime.
Let me make it clear through an example:
Let's say I have the following data:
user_id payment_type
1 UPI
1 NB
2 UPI
2 UPI
For the above, I only want user_id 2 as the output since for both the payments, it has used only 1 payment_type.
Can someone help?
A simple HAVING with COUNT should do the trick:
select user_id
from my_table
group by user_id
having count(distinct payment_type)=1;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=65f673a7df3ac0ee18c13105a2ec17ad
If you want to include payment_type in the result set , use:
select my.user_id,my.payment_type
from my_table my
inner join ( select user_id
from my_table
group by user_id
having count(distinct payment_type)=1
) as t1 on t1.user_id=my.user_id
group by my.user_id,my.payment_type ;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=cc4704c9e51d01e4e8fc087702edbe6e

MySQL: Create view with "inner join" and "count" on grouped data

My database contains a single table with lots of different data columns. Following simple representation shows the columns I am currently interested in:
Table Playlist:
id metadata lastplayed
===============================================
1 All Night 1571324631
2 Perfect Replacement 1571324767
3 One More Day 1571324952
4 Stay Awake 1571325184
5 Perfect Replacement 1571325386
6 All Night 1571325771
7 Close Enemies 1571326422
I already have a View which groups the metadata, so I can see all single occurrences of the songs and when they were last played (epoch seconds).
View 'Music' (desired result):
id metadata lastplayed count (*)
==============================================================
3 One More Day 1571324952 1
4 Stay Awake 1571325184 1
5 Perfect Replacement 1571325386 2
6 All Night 1571325771 2
7 Close Enemies 1571326422 1
The column "count" does not yet exist in the View, and I would like to include it via the existing SQL script that creates the View:
CREATE VIEW `Music` AS
SELECT
t1.`id`,
t1.`metadata`,
t1.`lastplayed`
FROM Playlist t1
INNER JOIN
(
SELECT `metadata`, MAX(`lastplayed`) AS `timestamp`
FROM Playlist
GROUP BY `metadata`
) t2
ON t1.`metadata` = t2.`metadata` AND t1.`lastplayed` = t2.`timestamp`
ORDER BY t1.`Id` ASC
So now I am running into the problem where and how to put my COUNT(metadata) AS count line, to get the desired result. When I add it in the top SELECT row, the table is reduced to a single data line with one song and the count of all data rows.
Put it in the inner select
CREATE VIEW `Music` AS
SELECT
t1.`id`,
t1.`metadata`,
t2.`lastplayed`,
t2.count
FROM Playlist t1
INNER JOIN
(
SELECT `metadata`, MAX(`lastplayed`) AS `timestamp`, COUNT(*) AS count
FROM Playlist
GROUP BY `metadata`
) t2
ON t1.`metadata` = t2.`metadata` AND t1.`lastplayed` = t2.`timestamp`
ORDER BY t1.`Id` ASC
You just need a simple aggregation through grouping by metadata column
CREATE OR REPLACE VIEW `Music` AS
SELECT MAX(id) AS id, `metadata`, MAX(`lastplayed`) AS lastplayed, COUNT(*) AS count
FROM Playlist
GROUP BY `metadata`

MySQL join tables and use two different records from joined table in two different columns of main table

I'm trying to create new table - new_data in which i'm going to store data about campaigns from two different tables
. I have table - campaign_revenue with a column data_date to indicate...data date, and another column revenue.
in another table - campaign_manager i have the columns revenue and revenue_yesterday . so what i want is to join the two tables and take the revenue and revenue_yesterday from campaign_revenue into new_data.
new record in the result table should look something like:
campaign_id | campaign_name | revenue | revenue_yesterday
43243242 | testing name | 109.02 | 159.43
where what we see is actually two records from campaign_revenue and for each date and campaign id and name from campaign_manager.
i've been trying quite few variations, but based on this answer
my last attempt was this:
SELECT campaign_id, campaign_name
FROM campaign_manager
UNION
SELECT
revenue
FROM campaign_revenue
WHERE data_date = '2018-02-13'
UNION
SELECT
revenue AS revenue_yesterday
FROM campaign_revenue
WHERE data_date = '2018-02-12'
it clearly didn't work but i hope it help''s understand what i'm trying to achive...thx
A self join would seem to be what you have in mind. You may join twice to the campaign_revenue table, once for today's revenue, and once for yesterday's revenue.
SELECT
cm.campaign_id,
cm.campaign_name,
cr1.data_date,
cr1.revenue AS revenue_today,
cr2.revenue AS revenue_yesterday
FROM campaign_manager cm
INNER JOIN campaign_revenue cr1
ON cm.campaign_id = cr1.campaign_id
LEFT JOIN campaign_revenue cr2
ON cm.campaign_id = cr2.campaign_id AND
cr1.data_date = DATE_ADD(cr2.data_date, INTERVAL 1 DAY)
-- WHERE cr1.data_date = CURDATE()
This answer assumes that your dates are contiguous, that is, there are no missing dates.
Try following query:
SELECT campaign_id, campaign_name FROM campaign_manager WHERE data_date IN ('2018-02-13', '2018-01-14', '2017-02-15')
UNION
SELECT title FROM data_table WHERE title IN ('2018-02-13', '2018-01-14')
you need to use two queries with union keyword.
For reference : you can go to 'UNION Syntax'

Guidance required for sql query

I have a database with one table as shown below. Here I'm trying to write a query to display the names of medication manufactured by the company that manufactures the most number of medications.
By looking at the table we could say the medication names which belongs to the company id 1 and 2 - because those company manufactures the most medication according to this table, but I'm not sure how to write a query for selecting the same i said before.
ID | COMPANY_ID | MEDICATION_NAME
1 1 ASPIRIN
2 1 GLUCERNA
3 2 SIBUTRAMINE
4 1 IBUPROFEN
5 2 VENOFER
6 2 AVONEN
7 4 ACETAMINOPHEN
8 3 ACETAMINO
9 3 GLIPIZIDE
Please share your suggestions. Thanks!
Several ways to do this. Here's one which first uses a subquery to get the maximum count, then another subquery to get the companies with that count, and finally the outer query to return the results:
select *
from yourtable
where companyid in (
select companyid
from yourtable
group by companyid
having count(1) = (
select count(1) cnt
from yourtable
group by companyid
order by 1 desc
limit 1
)
)
SQL Fiddle Demo
This Query might work. I have not tested but the logic is correct
SELECT MEDICATION_NAME
FROM TABLE where
COMPANY_ID=(SELECT
MAX(counted)
FROM ( SELECT COUNT(*) AS counted FROM TABLE ) AS counts);