I need the following sql query into laravel query or how can I run into laravel as it is. thanks
SELECT t.*
FROM (SELECT client_id,product_name, max(real_date) AS max_date
FROM api_hilbertis.transactions
WHERE active = 1 AND real_date <= '2019-03-01'
GROUP BY client_id, product_name) AS m
INNER JOIN api_hilbertis.transactions AS t
ON t.client_id = m.client_id
AND t.product_name = m.product_name
AND t.real_date = m.max_date
AND active = 1
ORDER BY real_date DESC;
You can use laravel raw queries.
Example HERE
So for your case it we could write something like:
$results = DB::select( DB::raw("
SELECT t.*
FROM (SELECT client_id,product_name, max(real_date) AS max_date
FROM api_hilbertis.transactions
WHERE active = 1 AND real_date <= '2019-03-01'
GROUP BY client_id, product_name) AS m
INNER JOIN api_hilbertis.transactions AS t
ON t.client_id = m.client_id
AND t.product_name = m.product_name
AND t.real_date = m.max_date
AND active = 1
ORDER BY real_date DESC"
));
EDIT: example with variables:
$someVariable = $request->input('some_variable');
$results = DB::select( DB::raw("SELECT * FROM some_table WHERE some_col = :somevariable"),
['somevariable' => $someVariable,]
);
Related
SELECT SUM(amount_paid) AS total_session FROM session
WHERE session.date = '2016-02-03' AND session.payment_status = 'PAID'
UNION
SELECT SUM(amount_paid) AS total_subscription FROM subscription
WHERE subscription.date_enrolled = '2016-02-03' AND subscription.payment_status = 'PAID'
I just want to display the result in two different columns with alias total_session and total_subscription. How can I do that using union?
Instead of a UNION, put each query as a subquery in a main SELECT
SELECT
(SELECT SUM(amount_paid) FROM session
WHERE session.date = '2016-02-03' AND session.payment_status = 'PAID') AS total_paid,
(SELECT SUM(amount_paid) FROM subscription
WHERE subscription.date_enrolled = '2016-02-03' AND subscription.payment_status = 'PAID') AS total_subscription
In that case, you can try doing a fake join like
SELECT xx.total_session, yy.total_subscription
FROM (
SELECT '1' as ID, SUM(amount_paid) AS total_session FROM session
WHERE session.date = '2016-02-03' AND session.payment_status = 'PAID') xx
JOIN (SELECT '1' as ID, SUM(amount_paid) AS total_subscription FROM subscription
WHERE subscription.date_enrolled = '2016-02-03' AND subscription.payment_status = 'PAID') yy
ON xx.ID = yy.ID;
I have two SQL queries that I would like to join into one:
select d.full_month, COUNT(*) amount
from fact_ticket t
join dim_queue q on t.queue_id = q.queue_id
join vt_scopes s on t.scope_id = s.scope_id
join dim_date d on t.create_date_id = d.date_id
where q.name = 'Support'
and year(GETDATE()) = YEAR(t.create_date)
and s.statusname not in ('discarded', 'closed')
group by d.full_month
order by 1;
and
select d.full_month, COUNT(*) amount
from fact_ticket t
join dim_queue q on t.queue_id = q.queue_id
join vt_scopes s on t.scope_id = s.scope_id
join dim_date d on t.create_date_id = d.date_id
where q.name = 'Support'
and year(GETDATE()) = YEAR(t.create_date)
and s.statusname in ('closed')
group by d.full_month
order by 1;
Both gives me now a result with a date column and an amount column, but I would like to get everything in one query where I would get date, amount 1, amount 2.
Is there an easy to do this?
You can use below query-
SELECT d.full_month,
COUNT(IF(s.statusname NOT IN ('discarded', 'closed'),1,NULL)) amount1,
COUNT(IF(s.statusname IN ('closed'),1,NULL)) amount2
FROM fact_ticket t
JOIN dim_queue q ON t.queue_id = q.queue_id
JOIN vt_scopes s ON t.scope_id = s.scope_id
JOIN dim_date d ON t.create_date_id = d.date_id
WHERE q.name = 'Support'
AND YEAR(GETDATE()) = YEAR(t.create_date)
GROUP BY d.full_month
ORDER BY 1;
2nd Edition: Even you can get benefit of index if exist on create_date by below query-
SELECT d.full_month,
COUNT(IF(s.statusname NOT IN ('discarded', 'closed'),1,NULL)) amount1,
COUNT(IF(s.statusname IN ('closed'),1,NULL)) amount2
FROM fact_ticket t
JOIN dim_queue q ON t.queue_id = q.queue_id
JOIN vt_scopes s ON t.scope_id = s.scope_id
JOIN dim_date d ON t.create_date_id = d.date_id
WHERE q.name = 'Support'
AND t.create_date>= DATE_FORMAT(NOW(),'%Y-01-01 00:00:00') AND t.create_date <= DATE_FORMAT(NOW(),'%Y-12-31 23:59:59');
GROUP BY d.full_month
ORDER BY 1;
Another way using sum function
SELECT
d.full_month,
SUM(s.statusname NOT IN ('discarded', 'closed')) amount,
SUM(s.statusname = 'closed') amount_closed
FROM
fact_ticket t
JOIN dim_queue q
ON t.queue_id = q.queue_id
JOIN vt_scopes s
ON t.scope_id = s.scope_id
JOIN dim_date d
ON t.create_date_id = d.date_id
WHERE q.name = 'Support'
AND YEAR(GETDATE ()) = YEAR(t.create_date)
GROUP BY d.full_month
ORDER BY 1 ;
I'm trying get last result from a table using the data_coleta (DATE) and servico_id as base. The query is working but is very slow. How can I optimize?
select t1.* from
amostra_ensaio_full t1
where
t1.cliente_id = 6 and t1.tipo_id <> 1
and t1.data_coleta = (SELECT max(s1.data_coleta) from amostra_ensaio_full s1 where t1.cliente_id = s1.cliente_id and s1.tipo_id <> 1 and s1.tipo_id = t1.tipo_id)
and t1.servico_id = (SELECT max(s2.servico_id) from amostra_ensaio_full s2 where t1.cliente_id = s2.cliente_id and s2.tipo_id <> 1 and s2.tipo_id = t1.tipo_id)
GROUP by t1.cliente_id , t1.tipo_id
You can probably speed up this query using indexes.
The query is:
select t1.*
from amostra_ensaio_full t1
where t1.cliente_id = 6 and t1.tipo_id <> 1 and
t1.data_coleta = (SELECT max(s1.data_coleta)
from amostra_ensaio_full s1
where t1.cliente_id = s1.cliente_id and
s1.tipo_id <> 1 and
s1.tipo_id = t1.tipo_id
) and
t1.servico_id = (SELECT max(s2.servico_id)
from amostra_ensaio_full s2
where t1.cliente_id = s2.cliente_id and
s2.tipo_id <> 1 and
s2.tipo_id = t1.tipo_id
)
GROUP by t1.cliente_id , t1.tipo_id;
You want the following index for the query: amostra_ensaio_full(cliente_id, tipo_id, servico_id).
The condition tipo_id <> 1 is unnecessary in the subquery, but it causes no harm.
Tks Gordon but the query still slow. Maybe I found the answer searching more.
SELECT a.*
FROM amostra_ensaio_full a
INNER JOIN
(
SELECT MAX(data_coleta) maxDate , tipo_id, cliente_id
FROM amostra_ensaio_full
GROUP BY cliente_id, tipo_id
) b ON a.cliente_id = b.cliente_id and a.tipo_id = b.tipo_id and b.maxDate = a.data_coleta
GROUP by a.cliente_id ,a.tipo_id
I am trying to add a group by SC_FRAMES.GROUPPRODUCTTYPE to this statement:
SELECT
SC_JOBS.CREATIONDATE,
(SELECT SUM(SC_JOBS.GROSSEXCLVAT) FROM SC_JOBS WHERE SC_FRAMES.GROUPPRODUCTTYPE = 'ABC' AND SC_FRAMES.JOBID = SC_JOBS.JOBSID AND SC_JOBS.INVOICEDATE < '1990-01-01') AS Product1,
(SELECT SUM(SC_JOBS.GROSSEXCLVAT) FROM SC_JOBS WHERE SC_FRAMES.GROUPPRODUCTTYPE = 'XYZ' AND SC_FRAMES.JOBID = SC_JOBS.JOBSID AND SC_JOBS.INVOICEDATE < '1990-01-01') AS Product2
FROM
SC_JOBS
INNER JOIN
SC_FRAMES ON SC_FRAMES.JOBID = SC_JOBS.JOBSID
WHERE
SC_JOBS.CREATIONDATE BETWEEN :StartDate AND :EndDate
ORDER BY
SC_JOBS.CREATIONDATE
Any suggestions please?
I think you want a query like this:
SELECT f.GROUPPRODUCTTYPE,
MIN(j.CREATIONDATE),
SUM(case when j.INVOICEDATE < '1990-01-01' then j.GROSSEXCLVAT else 0
end) as Product1
FROM SC_JOBS INNER j JOIN
SC_FRAMES f
ON f.JOBID = j.JOBSID
WHERE j.CREATIONDATE BETWEEN :StartDate AND :EndDate
GROUP BY f.GROUPPRODUCTTYPE
ORDER BY min(j.CREATIONDATE);
It replaces the subqueries with conditional aggregation, based on the invoice date.
Try this:
SELECT
SC_JOBS.CREATIONDATE,
(SELECT SUM(SC_JOBS.GROSSEXCLVAT) FROM SC_JOBS WHERE SC_FRAMES.GROUPPRODUCTTYPE = 'ATI' AND SC_FRAMES.JOBID = SC_JOBS.JOBSID AND SC_JOBS.INVOICEDATE < '1990-01-01') AS Product 1,
(SELECT SUM(SC_JOBS.GROSSEXCLVAT) FROM SC_JOBS WHERE SC_FRAMES.GROUPPRODUCTTYPE = 'ATI' AND SC_FRAMES.JOBID = SC_JOBS.JOBSID AND SC_JOBS.INVOICEDATE < '1990-01-01') AS Product 2
FROM
SC_JOBS
INNER JOIN
SC_FRAMES ON SC_FRAMES.JOBID = SC_JOBS.JOBSID
WHERE
SC_JOBS.CREATIONDATE BETWEEN :StartDate AND :EndDate
GROUP BY
SC_FRAMES.GROUPPRODUCTTYPE
ORDER BY
SC_JOBS.CREATIONDATE
Add GROUP BY SC_FRAMES.GROUPPRODUCTTYPE after the end of your WHERE statement and before your ORDER BY statement. Also change your AS values to not include spaces as I've encountered ploblems with this in the past, so use Product1 as opposed to Product 1
I have wrote the following SQL:
SELECT s.*, (SELECT COUNT(*) FROM orders o WHERE o.schedule_id = s.schedule_id AND o.content_id = s.content_id) as numofbookings
FROM schedules s
WHERE content_id = '{$contentid}'
AND DATEDIFF(`schedule_datetime_from`, now()) > 0
AND (SELECT COUNT(*) FROM orders o WHERE o.schedule_id = s.schedule_id AND o.content_id = s.content_id) < s.schedule_capacity
ORDER BY `s`.`schedule_datetime_from` ASC
Although I am concerned this could be wrote better without querying the orders table twice.
I tried AND numofbookings < s.schedule_capacity although this give error column not found.
SELECT s.*, COUNT(o.schedule_id) AS numofbookings
FROM schedules s
LEFT JOIN orders o
ON s.schedule_id = o.schedule_id
AND s.content_id = o.content_id
WHERE s.content_id = '{$contentid}'
AND DATEDIFF(s.schedule_datetime_from, now()) > 0
GROUP BY s.schedule_id, s.content_id
HAVING COUNT(o.schedule_id) < s.schedule_capacity
ORDER BY s.schedule_datetime_from ASC