Date split in columns in mysql - mysql

I have an events executed table wherein I want to separate columns based on the dates
SELECT Event_ID,Name,count(Customer_Id) FROM UNLIMITED.Event_Execution a
join UNLIMITED.Event_Master b on a.Event_Id=b.ID
Where Event_Execution_Date_ID = '20211007'
group by Event_Id
order by Count(Customer_Id) desc;
Desired output
Event_ID Name 20211006 20211007
1 Offer1 1,218 6,876
2 Offer2 10,212 4,123

You want conditional aggregation:
select
event_id,
name,
count(case when event_execution_date_id = '20211006' then customer_id end) as cnt_20211006,
count(case when event_execution_date_id = '20211007' then customer_id end) as cnt_20211007
from unlimited.event_execution a
join unlimited.event_master b on a.event_id = b.id
where event_execution_date_id in ('20211006', '20211007')
group by event_id
order by count(customer_id) desc;
Side notes:
a and b are bad alias names. use something mnemonic, e.g. e for the execution table and m for the master table.
When working with several tables, qualify all columns. Which table does customer_id belong to for instance?
Why count(customer_id)? Is customer ID a nullable column? Or does it reside in the execution table and you want to be able to outer join this table at some time and get the correct count of zero? Or what is the reason to count an expression and not just rows (count(*))?

Related

How to get least number of occurrence of data in other database table?

I want to get the Agent who has the least number of orders in table B.
also include Agent D. suppose as in the below table Agent D not having any order so in this case Required Answer is Agent D and if Agent D is also in Table B then I want Agent Who to have the least order.
if any more explanation is needed then please comment on the question I am ready to reply as soon as possible.
Start by summarising the order tableB in terms of the number of orders per agent:
SELECT Agent, count(agent) as orders FROM TableB group by agent;
Then JOIN this back to agents in TableA with a LEFT JOIN.
SELECT A.Agent, ifnull(B.orders,0) AS ORDERS
FROM TableA as A
LEFT JOIN
(SELECT Agent, count(agent) as orders
FROM TableB
GROUP BY agent
) AS B
ON (A.Agent = B.agent)
ORDER BY orders DESC;
This will return a list of all the agents along with their order totals from Table B, but any agents who have no orders will appear in this result with NULL orders. Use IFNULL() to place a zero in those values, and order by order total descending.
Output:
Agent
orders
B
4
C
3
A
2
D
0
You can use this method or this code to check
SELECT name,COUNT()
FROM tablename
GROUP BY name
ORDER BY COUNT() DESC;

Using JOIN in sql for two derived tables

Basically, I have two separate queries, which I need to somehow merge into one set of results.
![This is Table 1, which shows the sum of each group's salary]
1
Here is the queries I wrote to form the tables.
SELECT con_stagename, SUM(p_daily_salary) AS sum_salary
FROM CONTENDER, PARTICIPANT
WHERE p_contender = con_id
GROUP BY con_id;
SELECT MAX(sum_salary) AS max_salary
FROM (SELECT con_stagename, SUM(p_daily_salary) AS sum_salary
FROM CONTENDER, PARTICIPANT
WHERE p_contender = con_id
GROUP BY con_id) T2;
And the question is, if I want the result to be a single row of values, which the name of the group with the highest salary, and the actual amount. How would I do it? I've been trying to use JOIN operations but there was not luck.
SELECT con_stagename, SUM(p_daily_salary) AS sum_salary
FROM CONTENDER, PARTICIPANT
WHERE p_contender = con_id
GROUP BY con_id
ORDER BY 2 DESC
LIMIT 1

SQL beginner practice problems

Given two tables, orders (order_id, date, $, customer_id) and customers (ID, name)
Here's my method but I'm not sure if it's working & I'd like to know if there's faster/better way of solving these problems:
1) find out number of customers who made at least one order on date 7/9/2018
Select count (distinct customer_id)
From
(
Select customer_id from orders a
Left join customer b
On a.customer_id = b.ID
Group by customer_id,date
Having date = 7/9/2018
) a
2) find out number of customers who did not make an order on 7/9/2018
Select count (customer_id) from customer where customer_id not in
(
Select customer_id from orders a
Left join customer b
On a.customer_id = b.ID
Group by customer_id,date
Having date = 7/9/2018
)
3) find the date with most sales between 7/1 and 7/30
select date, max($)
from (
Select sum($),date from orders a
Left join customer b
On a.customer_id = b.ID
Group by date
Having date between 7/1 and 7/30
)
Thanks,
For problem 1, a valid solution might look like this:
SELECT COUNT(DISTINCT customer_id) x
FROM orders
WHERE date = '2018-09-07'; -- or is that '2018-07-09' ??
For problem 2, a valid solution might look like this:
SELECT COUNT(*) x
FROM customer c
LEFT
JOIN orders o
ON o.customer_id = x.customer_id
AND o.date = '2018-07-09'
WHERE o.crder_id IS NULL;
Assuming there are no ties, a valid solution to problem 3 might look like this:
SELECT date
, COUNT(*) sales
FROM orders
WHERE date BETWEEN '2018-07-01' AND '2018-07-30'
GROUP
BY date
ORDER
BY sales DESC
LIMIT 1;
The default format for a date in MySQL is YYYY-MM-DD, although this can be customized. You have to put quotes around it, otherwise it's treated as an arithmetic expression.
And none of your queries need to join with the customer table. The customer ID is already in the orders table, and you're not returning any info about the customers (like the name or address), you're just counting them.
1) You don't need the subquery or grouping.
SELECT COUNT(DISTINCT customer_id)
FROM orders
WHERE date = '2018-07-09'
2) Again, you don't need GROUP BY in the subquery. There's also a better pattern than NOT IN to get the count of non-matching rows.
SELECT COUNT(*)
FROM customer AS c
LEFT JOIN order AS o on c.id = o.customer_id AND o.date = '2018-07-09'
WHERE o.id IS NULL
See Return row only if value doesn't exist for various patterns to do this.
3) You can't use MAX($) in the outer query because the inner query doesn't return a column with that name. But even if you fix that, it still won't work, because the date column won't necessarily come from the same row that has the maximum. See SQL select only rows with max value on a column for more explanation of this.
You don't need a subquery at all. Use a query that returns the total sales for each day, then use ORDER BY to get the highest one.
SELECT date, SUM($) AS total_sales
FROM orders
WHERE date BETWEEN '2018-07-01' AND '2017-07-30'
GROUP BY date
ORDER BY total_sales DESC
LIMIT 1
If "most sales" is supposed to mean "most number of sales", replace SUM($) with COUNT(*).

MYSQL - GROUP BY 2 COLUMN ORDER BY CREATION DATE

I'm trying to get all results of my table with a GROUP BY on 2 columns and get the last insertions.
"Prices" table :
My Request :
SELECT DISTINCT p.*
FROM prices p
JOIN (
SELECT MAX(created_at) as "last_created"
FROM prices
WHERE station_id = 27210003
GROUP BY station_id, fuel_id) as sub
ON sub.last_created = p.created_at
WHERE p.station_id = 27210003
GROUP BY p.station_id, p.fuel_id
Results are 3 lines but wrong line because not last created in my DB -_-'
Please help me !!! >_<'
Thx
Since you're selecting a specific station_id in the WHERE clause, you don't need to include that in GROUP BY.
The subquery has to return the columns you're grouping on, and then you have to include them in the ON clause.
And you don't need GROUP BY in the outer query, since the JOIN should ensure that there's just one row for each fuel_id (unless there are duplicate created_at for the same fuel_id and station_id).
SELECT DISTINCT p.*
FROM prices p
JOIN (
SELECT fuel_id, MAX(created_at) as "last_created"
FROM prices
WHERE station_id = 27210003
GROUP BY fuel_id) as sub
ON sub.last_created = p.created_at AND sub.fuel_id = p.fuel_id
WHERE p.station_id = 27210003

My query returns each time the same (date2)

SELECT o.Date1, o.Date2
FROM customers AS c, products AS p, products_ids AS pi, orders AS o, temptable AS te
WHERE p.productid = pi.productidD
AND pi.prodno = te.prodno
AND c.custid = o.custid
AND o.custid = te.custid
AND te.custid = '24'
GROUP BY pi.productiD
The result of the query returns each time the same date(of one row) to all the rows,even if the dates are different inside mysql.
As has been mentioned it is worth switching to the newer ANSI 92 JOIN syntax for clarity, this can avoid accidental cross joins, so your query would become:
SELECT o.Date1, o.Date2
FROM customers AS c
INNER JOIN orders AS o
ON c.custid = o.custid
INNER JOIN temptable AS te
o.custid = te.custid
INNER JOIN products AS p
ON pi.prodno = te.prodno
INNER JOIN products_ids AS pi
ON p.productid = pi.productidD
WHERE te.custid = '24'
GROUP BY pi.productiD;
However, this is not the problem in your query, the problem is the fact that you are abusing the functionality within MySql whereby you can select items that are not part of the group by:
Here you are telling the query to select 1 row per distinct value for pi.ProductID, there could be multiple different values for o.Date1 and o.Date2 for each pi.ProductID, and you are giving the query no hints as to which of these multiple possibilities to choose from.
Using columns in the select that are not in the group by is permitted by ANSI standards but only when the columns in the select are functionally dependant on columns within the group by, this is very hard to adhere to so most DBMS simply do not allow columns in the select that are not in the group by.
To demonstrate consider this dataset (T)
OrderID ProductID Date1 Date2
1 1 20130401 20130402
2 1 20130402 20130403
3 2 20130403 20130404
4 2 20130404 20130405
5 2 20130405 20130406
If (as in your case) you did:
SELECT OrderID, ProductID, Date1, Date2
FROM T
GROUP BY ProductID
You would probably get:
OrderID ProductID Date1 Date2
1 1 20130401 20130402
3 2 20130403 20130404
Just taking the first row for each product ID, however since the query is non deterministic it would be equally correct for the query to return the last row for each productID:
OrderID ProductID Date1 Date2
2 1 20130402 20130403
5 2 20130405 20130406
It is a common myth that adding order by will help this, e.g.
SELECT OrderID, ProductID, Date1, Date2
FROM T
GROUP BY ProductID
ORDER BY OrderID;
MySql determines the rows to be returned before applying the order by, so even adding ORDER BY OrderID does not guarantee the first order for each productID is returned.
The MySQL Docs state
The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause.
Finally to elaborate on what I said about functionally dependant columns, because in this dataset OrderID is a primary key, according to ANSI standards you could write:
SELECT OrderID, ProductID, Date1, Date2
FROM T
GROUP BY OrderID;
So, while I have not really answered your question I hopefully have shown where you are going wrong. You really need to establish what you are trying to achieve by the group by, and if you still haven't got a solution then i'd suggest a new, more constructive question, with sample data and an expected output with clear rules as to why the expexted output is expexted.