Inserting using a select with or - mysql

I am trying to to perform an insert using the following:
INSERT INTO stock_withholds (s_id, mob, paddock, product, completed_date, withhold_until_date, ESI_withhold_until_date)
SELECT stk_id AS s_id,
mob,
paddock,
product,
completed_date,
withhold_until_date,
ESI_withhold_until_date
FROM stock_current
WHERE (withhold_until_date >=CURDATE()
OR (ESI_withhold_until_date >= CURDATE()
AND stock_current.stk_id NOT IN
(SELECT s_id
FROM stock_withholds)
If I rerun the query it duplicates the records.
Desired result is if either the withhold_until_date or ESI_withhold_until_date are greater then current date the records would inserted.
Thanks

Related

Your Query does not include the specified expression "ID" as part of an aggregate function. MS acces

Hi dear developer friends, I am trying the following code but I am getting this error : Your Query does not include the specified expression "ID" as part of an aggregate function.
The code is
SELECT ID, Date, Time, Status, BoxType, Material, Rack, EmployeeNr, Transaction FROM Records
WHERE Transaction<100 AND ID NOT IN
(SELECT `ID` FROM Records a WHERE EXISTS
(SELECT `ID` FROM records b WHERE b.Transaction>100 AND (b.Date=a.Date) AND (b.Time > a.Time) AND (b.Transaction-100=a.Transaction)))
UNION
SELECT ID, Date, Time, Status, BoxType, Material, Rack, EmployeeNr, Transaction FROM records a WHERE EXISTS
(SELECT `ID` FROM records b WHERE b.Transaction>100 AND (b.date=a.date) AND (b.time > a.time) AND (b.Transaction-100=a.Transaction))
GROUP BY Transaction
HAVING COUNT(Transaction)>1
Your are both grouping by and counting Transaction which doesn't make much sense.
If counting on one field, the remaining must be grouped by or aggregated somehow. Also, reserved words must be bracketed (Status and Transaction may need as well), and you would not pull the string "ID" but instead the field from the subqueries.
So, as we have no idea what you are trying to achieve, no direct solution is possible, but this should get you started:
SELECT
ID, [Date], [Time], Status, BoxType, Material, Rack, EmployeeNr, Transaction
FROM
Records
WHERE
Transaction < 100 AND ID NOT IN
(SELECT ID FROM Records a WHERE EXISTS
(SELECT ID FROM Records b WHERE
b.Transaction>100 AND (b.Date=a.Date) AND (b.Time > a.Time) AND (b.Transaction-100=a.Transaction)))
UNION
SELECT
ID, [Date], [Time], Status, BoxType, Material, Rack, EmployeeNr, Transaction
FROM
Records a
WHERE EXISTS
(SELECT ID FROM Records b WHERE
b.Transaction>100 AND (b.date=a.date) AND (b.time > a.time) AND (b.Transaction-100=a.Transaction))
GROUP BY
ID, [Date], [Time], Status, BoxType, Material, Rack, EmployeeNr, Transaction
HAVING
COUNT(Transaction) > 1

I want to count rows of column between dates

Table contains columns id, fid, created_date.
fid is not present in all rows.
Here is my sql query:
select count(*) fid from users where created_on between '2017-01-06 00:00:000' AND '2017-01-06 23:59:59.997' not in ('');
I want to count fid rows between dates, I tried with this query but it is not returning proper output, I am getting total count in result, I want count between the dates I entered
Try
select count(*) from users where created_on between '2017-01-06 00:00:00' AND '2017-01-06 23:59:59';

Is there any way to update a column of a table with WTD values in one go?

I am trying to update a table with WTD values for specific date. Everytime while updating it I have to enter the date manually in the condition. Is there any method to pass the date values dynamically in conditions such that my WTD values get updated in one go?
Here is my update query:
update table1, (Select sum(sales) as sales from table1 where
day between subdate('2016-09-01', Interval weekday('2016-09-01') Day) and '2016-09-01') src
set WTD_Sales=src.sales
where day='2016-09-01'
So here I want to replace the statically added date '2016-09-01' with a variable that can fetch date from same table itself row by row dynamically
Your query looks wrong to me. Change it like below using a JOIN. Assuming there is a id column present in the table.
update table1 t1
join ( Select sum(sales) as sales, id, some_date_column
from table1
where day between subdate('2016-09-01', Interval weekday('2016-09-01') Day)
and '2016-09-01') src on t1.id = src.id
set t1.WTD_Sales = src.sales
where t1.day = src.some_date_column;

mysql avg value with specified number of rows

i have a simple table with
value (int), created (timestamp)
i would like to do a query that return an arbitrary number of rows with avg (value) and avg(created). The grouping function is the order by of created, means that if i ask for 2 rows, i should obtain a set based on the first rows ordered by created.
i have the following table:
create table log(value int,created timestamp);
insert into log values
(1,'2016-01-01 00:00:00'),
(2,'2016-01-01 01:00:00'),
(3,'2016-01-01 02:00:00'),
(4,'2016-01-01 03:00:00'),
(5,'2016-01-01 04:00:00'),
(6,'2016-01-01 05:00:00'),
(7,'2016-01-01 06:00:00'),
(8,'2016-01-01 07:00:00'),
(9,'2016-01-01 08:00:00');
http://sqlfiddle.com/#!9/b9a94
i want to retrive 3 rows that should be
2-2016-01-01 01:00:00
5-2016-01-01 04:00:00
8-2016-01-01 07:00:00
it's possible to do it in a single query without using java or php processing?
For example when you group by 3, ordered by creation date. You can change 3 to the size you want to group by.
SELECT avg(sub.value), avg(sub.created)
from (
SELECT #row_number:=#row_number+1 AS row_number,value, created
FROM log, (SELECT #row_number:=0) AS t
ORDER BY created
) sub
group by floor((sub.row_number-1)/3)
UPDATE
if you always want it to be divided in 3 groups based on the number of rows you can do the following:
SELECT avg(sub.value), avg(sub.created)
from (
SELECT #row_number:=#row_number+1 AS row_number, floor((#row_number-1)/c.num) groupid,value, created
FROM log,
(SELECT #row_number:=0) AS t,
(SELECT ceil(COUNT(*)/3) num FROM log) c
ORDER BY log.created
) sub
GROUP BY sub.groupid

SQL Query to get the last set of distinct records with some conditions

I have the following table:
I'm trying to find a way to get the records for those customers that have expired, and then update the table accordingly (by update I mean add an a new record with entry 'SERVICE EXPIRED' with the customer_id of the relevant customer).
If you look at the bottom of the table, you will notice two records with the entry 'SERVICE EXPIRED' for already existing customers (customer_id 11 and 16).
I'm looking for a SQL Query that will:
Get the last set of distinct records by customer_id
Exclude records for the same customer_id from the resulting resultset that have the entry 'SERVICE EXPIRED' or status_id of 2 appearing later on in the table
If I use the following:
SELECT MAX(id) FROM mytable WHERE status_id != '2' AND expiry < '2012-12-26 19:00:00' GROUP BY customer_id
It will return ids 1, 11, 13, and 16. However, I don't want ids 11 and 16 because the expiry status has already been noted later on in the table (see the last two records of the table), and id 1 has been renewed as can be seen with an updated expiry date in id 3 later. All I want is id 13 because that is the only expired record that does not have a 'SERVICE EXPIRED' entry that appears later in the table.
I'm looking for a SQL Query that will enable me capture this requirement.
Thanks in advance
After some fiddling around I managed to come up with a solution:
SELECT MAX(id)
FROM mytable
WHERE status_id != '2'
AND expiry < '2012-12-26 19:00:00'
AND customer_id NOT IN (SELECT MAX(customer_id) FROM mytable WHERE status_id = '2' GROUP BY customer_id)
GROUP BY customer_id
Thanks #JupiterP5 for pointing me in the right direction.
Regards,
Your requirement is equivalent to finding "n" records after the last expiry on a record. The following query returns all records after the last expiry for a given customer:
select t.*
from t join
(select t.customer_id, MAX(id) as maxid
from t
where status_id = 2
) texp
on t.customer_id = texp.customer_id and
t.id > texp.maxid
By using variables cleverly, you can enumerate these to get the last "n". However, do you really need a fixed number? Why not all of them? Why not just one of them?
It's not efficient, but this should work.
SELECT MAX(id)
FROM mytable
WHERE status_id != '2'
AND expiry < '2012-12-26 19:00:00'
AND id NOT IN (SELECT id FROM mytable where status_id = 2)
GROUP BY customer_id
Edit: Missed the service renewed case. I'll update if I think of something.