I have two date columns in my table and I need a list of all dates which are in the table.
I tried it with the following statement already
SELECT GREATEST(
IFNULL(DATE(record_date), 0),
IFNULL(DATE(edit_date), 0)
) as 'date_val'
FROM TBL_EXAMPLE
GROUP BY date_val
ORDER BY date_val;
With this SQL statement some of the dates getting lost and I don't know why. I just want a complete list of all dates which are in this table (DISTINCT, descending)
This is a job for UNION.
SELECT record_date AS dt FROM TBL_EXAMPLE
UNION
SELECT edit_date AS dt FROM TBL_EXAMPLE
ORDER BY dt DESC;
Union eliminates nulls and duplicates.
It makes some years since I studied sql so, I am having trouble getting a
get a distinct list of formatted dates sorted using Mysql. I don't need to show my table because I only use one column of datetime
data_vencimento datetime
If I have 2018-10-29 , 2018-10-29, 2018-09-29. It should be sorted as
10/2018
09/2018
notice that the repeated date is "removed" and a sorted list of formatted date was generated
here is my attempt. It is generating repeated results.
select distinct(data_vencimento), date_format( data_vencimento,'%m/%Y' ) as data from (
select data_vencimento from custo_extra_movimento where id_admin
union
select data_vencimento as data from custo_fixo_movimento where id_admin
union
select data_vencimento as data from custo_variavel_movimento where id_admin) as tbl order by data_vencimento desc ;
Distinct is not a function; so you do not need to use parentheses with Distinct.
Nevertheless, you need a Distinct combination of Month and Year, so you can use Group By instead, alongwith date functions like Month() and Year().
Also, in your Union queries, defining data alias for second and third Select query will not serve any purpose. MySQL would consider the first Select query column name only.
Do the following instead:
SELECT
YEAR(tbl.data_vencimento) AS year_data,
MONTH(tbl.data_vencimento) AS month_data,
DATE_FORMAT( MAX(tbl.data_vencimento),'%m/%Y' ) AS data
FROM (
select data_vencimento from custo_extra_movimento where id_admin
union
select data_vencimento from custo_fixo_movimento where id_admin
union
select data_vencimento from custo_variavel_movimento where id_admin
) AS tbl
GROUP BY year_data, month_data
ORDER BY year_data DESC, month_data DESC
I think this is sufficient:
select date_format(data_vencimento, '%m/%Y') as data from custo_extra_movimento where id_admin
union -- on purpose to remove duplicates
select date_format(data_vencimento, '%m/%Y') as data from custo_fixo_movimento where id_admin
union -- on purpose to remove duplicates
select date_format(data_vencimento, '%m/%Y') as data from custo_variavel_movimento where id_admin
order by data desc;
To be honest, I am a little unclear on the logic for the ordering, so that might be off.
I have a database with over 100,000 records. I'm trying to get all customers who ordered only once searching by customer's email field (OrderEmail).
The SQL query is running for 10 minutes and then times out.
If I use short date ranges, I can get results but it still takes over 3 minutes.
How can I optimize the syntax to get it work?
SELECT
tblOrders.OrderID,
tblOrders.OrderName,
tblOrders.OrderEmail,
tblOrders.OrderPhone,
tblOrders.OrderCountry,
tblOrders.OrderDate
FROM
tblOrders
LEFT JOIN tblOrders AS orders_join ON orders_join.OrderEmail = tblOrders.OrderEmail
AND NOT orders_join.OrderID = tblOrders.OrderID
WHERE
orders_join.OrderID IS NULL
AND (tblOrders.OrderDate BETWEEN '2015-01-01' AND '2017-03-01')
AND tblOrders.OrderDelivered = - 1
ORDER BY
tblOrders.OrderID ASC;
I would expect the below to work - but I can't test it as you don't provide sample data. Well, I added a temporary table definition that could be used for the query ....
But , if you could actually change the data model to use an INTEGER id for the entity who placed the order (instead of a VARCHAR() email address), you would get considerably faster.
CREATE TEMPORARY TABLE IF NOT EXISTS
tblorders(orderid,ordername,orderemail,orderphone,ordercountry,orderdate) AS (
SELECT 1,'ORD01','adent#hog.com' ,'9-991' ,'UK', DATE '2017-01-01'
UNION ALL SELECT 2,'ORD02','tricia#hog.com','9-992' ,'UK', DATE '2017-01-02'
UNION ALL SELECT 3,'ORD03','ford#hog.com' ,'9-993' ,'UK', DATE '2017-01-03'
UNION ALL SELECT 4,'ORD04','zaphod#hog.com','9-9943','UK', DATE '2017-01-04'
UNION ALL SELECT 5,'ORD05','marvin#hog.com','9-9942','UK', DATE '2017-01-05'
UNION ALL SELECT 6,'ORD06','ford#hog.com' ,'9-993' ,'UK', DATE '2017-01-06'
UNION ALL SELECT 7,'ORD07','tricia#hog.com','9-992' ,'UK', DATE '2017-01-07'
UNION ALL SELECT 8,'ORD08','benji#hog.com' ,'9-995' ,'UK', DATE '2017-01-08'
UNION ALL SELECT 9,'ORD09','benji#hog.com' ,'9-995' ,'UK', DATE '2017-01-09'
UNION ALL SELECT 10,'ORD10','ford#hog.com' ,'9-993' ,'UK', DATE '2017-01-10'
)
;
SELECT
tblOrders.OrderID
, tblOrders.OrderName
, tblOrders.OrderEmail
, tblOrders.OrderPhone
, tblOrders.OrderCountry
, tblOrders.OrderDate
FROM tblOrders
JOIN (
SELECT
OrderEmail
FROM tblOrders
GROUP BY
OrderEmail
HAVING COUNT(*) = 1
) singleOrders
ON singleOrders.OrderEmail = tblOrders.OrderEmail
ORDER BY OrderID
;
OrderID|OrderName|OrderEmail |OrderPhone|OrderCountry|OrderDate
1|ORD01 |adent#hog.com |9-991 |UK |2017-01-01
4|ORD04 |zaphod#hog.com|9-9943 |UK |2017-01-04
5|ORD05 |marvin#hog.com|9-9942 |UK |2017-01-05
As you can see, it returns Mr. Dent, Zaphod and Marvin, who all occur only once in the example data.
Another approach that might work is that you group by email address and get only those with one entry. It may behave unpredictably if you want to get customers with multiple orders but it should be fine for this particular case:
SELECT
tblOrders.OrderID,
tblOrders.OrderName,
tblOrders.OrderEmail,
tblOrders.OrderPhone,
tblOrders.OrderCountry,
tblOrders.OrderDate,
count(tblOrders.OrderID) as OrderCount
FROM
tblOrders
WHERE
tblOrders.OrderDate BETWEEN '2015-01-01' AND '2017-03-01'
AND tblOrders.OrderDelivered = - 1
GROUP BY
tblOrders.OrderEmail
HAVING
OrderCount = 1
ORDER BY
tblOrders.OrderID ASC;
Also, I suspect that if you're seeing so long query times with just 100k records, you probably don't have an index on the OrderEmail column - I suggest setting that up and that might help with your original queries as well.
This does not work in Oracle, or SQL Server but it does work in MySQL and SQLite. So, while the code is not portable between different RDBMS, it works for this particular case.
I have 2 tables both containing an event and date column. Is there a way to combine the results of both column's event field into one and sort them by their date field. That way only a single (and combined) event is returned instead of 2.
SELECT event,date FROM table1
UNION
SELECT event,date FROM table2 ORDER BY date
When using UNION you use ORDER by at bottom query it will order marged query
You can't use it except bottom query anyway it should throw an error
SELECT a.event, MAX(a.date) date
FROM
(
SELECT event, date FROM TableA
UNION
SELECT event, date FROM TableB
) a
GROUP BY a.event
ORDER BY a.date DESC
I have "users" table with fields
user_name, user_id
I have data tables like
data_table_2012_10
data_table_2012_11
data_table_2012_12
data_table_2013_01
data_table_2013_02
each table contains the following fields
user_id, type ('ALARM', 'EMERGENCY', 'ALIVE', 'DEAD'), date_time
There will be millions of records in each table.
I have to select the count of type from the data_tables within the time frame given by the user, as well as have to get the corresponding name of the user with the help of user_id.
Can some one help me out with the best solution.
Try this query where DATE1 and DATE2 is your date range. You should union all tables in the inner query. Also you can try to make a query dynamically to include in the inner query only those tables that are in a date range you use:
select t.user_id,t.type, MAX(users.user_name), SUM(t.cnt)
from
(
select user_id,type,count(*) cnt
from data_table_2012_10 where date_time between DATE1 and DATE2
group by user_id,type
union all
select user_id,type,count(*) cnt
from data_table_2012_11 where date_time between DATE1 and DATE2
group by user_id,type
union all
.........................................
union all
select user_id,type,count(*) cnt
from data_table_2013_02 where date_time between DATE1 and DATE2
group by user_id,type
) t
left join users on (t.user_id=users.user_id)
group by t.user_id,t.type
Remember not to use UNION, but UNION ALL as UNION will return only merge similar rows into one and that may cause problem