Convert MySQL query to Laravel models - mysql

SELECT
clockin.working_day as cdate,
clockin.,
sch_week.,
user.schedule_id,
user.username,
(
SELECT
GROUP_CONCAT(time separator '==')
from
clockin
WHERE
employee_no = user.employee_no
AND working_day = cdate
GROUP by
working_day
) as time
FROM
user_personal as user
JOIN clockin
inner join schedule_week as sch_week on user.schedule_id = sch_week.schedule_id
and week_day = date_format(working_day, '%a')
where
month(working_day) = month(
current_date()
)
GROUP by
user.employee_no,
clockin.working_day
ORDER by
clockin.working_day desc,
user.employee_no;

Related

I am missing an alias for a derived table

I know, this question has been asked very often but I know my error, I know how I could fix it, but I canĀ“t find the point where the error is. In my opinion, all the subqueries have different and unique names, I even gave the columns different names then the subqueries. Any help would be appreciated. Where is the point I am missing an alias?
Whenever I am trying to run this query I get the response "Every derived table must have its alias", which is an understandable error message, but I can't figure out where my error is located.
SELECT
mso.entity_id,
GROUP_CONCAT(msh.comment) AS comment,
msoa.lastname,
base_grand_total,
mso.created_at,
mso.status,
marketplace_order_id AS amazon_order_id,
clvData.recurrenceRate,
clvData.avgRepRate
FROM
mag_sales_flat_order AS mso
LEFT JOIN mag_sales_flat_order_status_history AS msh ON mso.entity_id = msh.parent_id
LEFT JOIN mag_sales_flat_order_address AS msoa ON mso.entity_id = msoa.parent_id
left join (
select
cast(((cet.cec - cnt.cnc) / cst.csc) AS decimal(6, 2)) as recurrenceRate,
avg(repRate.countedOrders) AS avgRepRate
from(
Select
*,
(
select
count(customer_email) AS csc
from
mag_sales_flat_order
where
created_at between '2017-01-01'
and '2017-12-31'
) AS cst,
(
select
count(customer_email) AS cec
from
mag_sales_flat_order
where
created_at between '2017-01-01'
and '2020-12-31'
) AS cet,
(
select
count(mso_new.customer_email) AS cnc
from
(
select
*
from
mag_sales_flat_order
where
created_at between '2018-01-01'
and current_date()
) AS mso_new
left join (
select
*
from
mag_sales_flat_order
where
created_at between '2017-01-01'
and '2017-12-31'
) AS mso_old on mso_new.customer_email = mso_old.customer_email
)) AS cnt
join (
select
customer_email,
count(grand_total) as countedOrders,
sum(grand_total) as summedOrders
from
mag_sales_flat_order
group by
customer_email
) AS repRate on cl.customer_email = repRate.customer_email
) AS clvData on mso.customer_email = clvData.customer_email
WHERE
store_id IN({$store['id']})
AND (
mso.status = 'complete'
OR mso.status = 'closed'
OR mso.status = 'processing'
OR mso.status = 'exported'
OR mso.status LIKE 'pending%'
)
AND (
DATE_FORMAT(mso.created_at, '%Y-%m-%d') >= '$begin_date'
)
AND (
DATE_FORMAT(mso.created_at, '%Y-%m-%d') <= '$end_date'
)
GROUP BY
entity_id;
SELECT
mso.entity_id,
GROUP_CONCAT(msh.comment) AS comment,
msoa.lastname,
base_grand_total,
mso.created_at,
mso.status,
marketplace_order_id AS amazon_order_id,
clvData.recurrenceRate,
clvData.avgRepRate
FROM mag_sales_flat_order AS mso
LEFT JOIN mag_sales_flat_order_status_history AS msh ON mso.entity_id = msh.parent_id
LEFT JOIN mag_sales_flat_order_address AS msoa ON mso.entity_id = msoa.parent_id
LEFT JOIN
(
SELECT cast(((cet.cec - cnt.cnc) / cst.csc) AS decimal(6, 2)) as recurrenceRate, avg(repRate.countedOrders) AS avgRepRate
FROM
(
SELECT *,
(
SELECT count(customer_email) AS csc
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2017-01-01' AND '2017-12-31'
) AS cst,
(
SELECT count(customer_email) AS cec
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2017-01-01' AND '2020-12-31'
) AS cet,
(
SELECT count(mso_new.customer_email) AS cnc
FROM
(
SELECT *
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2018-01-01' AND getdate()
) AS mso_new
LEFT JOIN
(
SELECT *
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2017-01-01' AND '2017-12-31'
) AS mso_old on mso_new.customer_email = mso_old.customer_email
) AS cnt
) as cl
JOIN
(
SELECT customer_email, count(grand_total) as countedOrders, sum(grand_total) as summedOrders
FROM mag_sales_flat_order
GROUP BY customer_email
) AS repRate on cl.customer_email = repRate.customer_email
) AS clvData on mso.customer_email = clvData.customer_email
WHERE store_id IN({ $ store ['id'] })
AND
(
mso.status = 'complete'
OR mso.status = 'closed'
OR mso.status = 'processing'
OR mso.status = 'exported'
OR mso.status LIKE 'pending%'
)
AND
(
DATE_FORMAT(mso.created_at, '%Y-%m-%d') >= '$begin_date'
)
AND
(
DATE_FORMAT(mso.created_at, '%Y-%m-%d') <= '$end_date'
)
GROUP BY entity_id;

Join table on laravel

SELECT title AS quiz_namenik, fullname AS profile_name, nik, store_code,
siebel_name AS store_name, MONTHNAME(start_date) AS `month`, score,
start_date, end_date,profil.created_at AS account_created_date,
profil.updated_at AS account_last_update
FROM
(
SELECT users.id, fullname, nik, siebel_name,store_code,
users.created_at, users.updated_at
FROM users
INNER JOIN stores ON users.store_id = stores.id
) AS profil,
(
SELECT kepo_quizs.id, score.user_id, title, score, start_date, end_date
FROM kepo_quizs
LEFT JOIN kepo_user_score AS score ON score.quiz_id = kepo_quizs.id
WHERE `activity_category_id` = '2'
) AS quiz
WHERE quiz.user_id = profil.id
AND (`start_date` >= '2019-01-01' AND `end_date` <= '2019-12-31')
ORDER BY title ASC, fullname ASC
That's my query that i want to change to laravel joins, can help me please
You can use the below code
DB::SELECT("SELECT title AS quiz_namenik, fullname AS profile_name, nik, store_code,
siebel_name AS store_name, MONTHNAME(start_date) AS `month`, score,
start_date, end_date,profil.created_at AS account_created_date,
profil.updated_at AS account_last_update
FROM
(
SELECT users.id, fullname, nik, siebel_name,store_code,
users.created_at, users.updated_at
FROM users
INNER JOIN stores ON users.store_id = stores.id
) AS profil,
(
SELECT kepo_quizs.id, score.user_id, title, score, start_date, end_date
FROM kepo_quizs
LEFT JOIN kepo_user_score AS score ON score.quiz_id = kepo_quizs.id
WHERE `activity_category_id` = '2'
) AS quiz
WHERE quiz.user_id = profil.id
AND (`start_date` >= '2019-01-01' AND `end_date` <= '2019-12-31')
ORDER BY title ASC, fullname ASC");

Operand should contain 1 column(s) - in mysql query

I have the following complex query that is giving me an error
Operand should contain 1 column(s)
Can anyone suggest what is wrong
SELECT
t.user_id AS user_id,
t.organisation_id AS organisation_id,
t.firstname AS firstname,
t.surname AS surname,
t.username AS username,
t.year_id AS year_id,
t.form_name AS form_name,
t.House AS House,
rcPoints.total AS milestoneRedeemedCodesTotal,
rcFilteredPoints.total AS redeemedCodesTotalFiltered,
(
COALESCE (rcFilteredPoints.total, 0) - COALESCE (milestoneHistory.total, 0)
) AS redeemedCodesTotalAvailableFiltered,
ABS(
FLOOR(
(
COALESCE (rcFilteredPoints.total, 0) - COALESCE (milestoneHistory.total, 0)
) / 1000
) * 1000
) AS redeemedCodesTotalTowardsMilestone,
ABS(
FLOOR(
(
COALESCE (rcFilteredPoints.total, 0) - COALESCE (milestoneHistory.total, 0)
) / 1000
)
) AS redeemedCodesMilestoneTriggers,
COALESCE (milestoneHistory.total, 0) AS historyTotal
FROM
`myuser` `t`
LEFT JOIN (
SELECT
rc.user_id AS user_id,
SUM(rc.school_points) AS total
FROM
`redeemed_codes` `rc`
INNER JOIN myuser m ON (m.user_id = rc.user_id)
WHERE
(rc.date_redeemed >= 0)
AND (m.organisation_id = 58022)
GROUP BY
rc.user_id
) AS rcPoints ON (rcPoints.user_id = t.user_id)
LEFT JOIN (
SELECT
rc.user_id AS user_id,
SUM(rc.school_points) AS total
FROM
`redeemed_codes` `rc`
INNER JOIN myuser m ON (m.user_id = rc.user_id)
WHERE
(rc.date_redeemed >= 0)
AND (m.organisation_id = 58022)
GROUP BY
rc.user_id
) AS rcFilteredPoints ON (
rcFilteredPoints.user_id = t.user_id
)
LEFT JOIN (
SELECT
mh.user_id AS user_id,
mh.milestone_id AS milestone_id,
MAX(mh.points_when_triggered) AS total
FROM
`milestone_history` `mh`
WHERE
mh.milestone_id = 13
GROUP BY
mh.user_id
) AS milestoneHistory ON (
milestoneHistory.user_id = t.user_id
)
WHERE
(
(
SELECT
COALESCE (count(*), 0)
FROM
milestone_history mha
WHERE
mha.milestone_id = 13
AND mha.user_id = t.user_id
) = 0
)
AND (t.organisation_id = 58022)
AND
(
SELECT * FROM
redeemed_codes t1
WHERE
organisation_id = 1
AND
(
SELECT
sum(school_points)
FROM
redeemed_codes t2
WHERE
t2.redeemed_code_id <= t1.redeemed_code_id
) >= 1000
ORDER BY redeemed_code_id
LIMIT 1
)
GROUP BY
t.user_id
ORDER BY
redeemedCodesMilestoneTriggers DESC
LIMIT 1
Your query might have multiple errors, but this condition in the WHERE clause is definitely suspect and would lead to that error:
AND (SELECT *
FROM redeemed_codes t1
WHERE organisation_id = 1 AND
(SELECT sum(school_points)
FROM redeemed_codes t2
WHERE t2.redeemed_code_id <= t1.redeemed_code_id
) >= 1000
ORDER BY redeemed_code_id
LIMIT 1
)
I have no idea what you are trying to do. Sometimes, the solution is simply EXISTS:
EXISTS (SELECT *
FROM redeemed_codes t1
WHERE organisation_id = 1 AND
(SELECT sum(school_points)
FROM redeemed_codes t2
WHERE t2.redeemed_code_id <= t1.redeemed_code_id
) >= 1000
)

MYSQL Query with Multiple Selects from Same Table

Getting an error
Operand should contain 1 column(s)
PK is ID
The table just dumps data in to the table
need to get the earliest date qty and the latest date qty and display on the same column
Any help appreciated
SELECT ebx_r_history.ItemNumber,
(SELECT r.QuantitySold as newqty, r.lastupdate as lu
FROM ebx_r_history r
WHERE ebx_r_history.ItemNumber = r.ItemNumber AND ebx_r_history.SKU = r.SKU
ORDER BY r.LastUpdate ASC
LIMIT 1),
(SELECT r.QuantitySold as newqty, r.lastupdate as lu
FROM ebx_r_history r
WHERE ebx_r_history.ItemNumber = r.ItemNumber AND ebx_r_history.SKU = r.SKU
ORDER BY r.LastUpdate DESC
LIMIT 1)
FROM
ebx_r_history
GROUP BY ebx_r_history.ItemNumber,
ebx_r_history.SKU
ORDER BY ebx_r_history.LastUpdate
This version may offer a simplified and faster alternative for you. The inner query for "AllItems" does both a min and max of the last update on a per-item number/sku basis, although I believe they would be one-in-the-same record.
So now, join that results back to the history data by item/sku and only those that match either the min or max date. If a true date/time, there would expect to only be one anyhow, vs just a date-only. So, since there would be 2 possible records (one for the min, one for the max), I am applying a MAX( IIF( )) for each respective matching the minimum and maximum dates respectively and must retain the group by clause.
Note, if you are dealing with date-only entries, or possibilities of the exact same item/sku and lastupdate are the same to the second, then you would need an approach more towards limit 1 per ascending/descending basis.
SELECT
AllItems.ItemNumber,
AllItems.SKU,
AllItems.MinUpdate,
MAX( IIF( rh.lastupdate = AllItems.MinUpdate, rh.Quantity.Sold, 0 )) as QtyAtMinDate,
AllItems.MaxUpdate,
MAX( IIF( rh.lastupdate = AllItems.MaxUpdate, rh.Quantity.Sold, 0 )) as QtyAtMaxDate
from
( SELECT
r.ItemNumber,
r.SKU,
MIN( r.lastupdate ) as MinUpdate,
MAX( r.lastupdate ) as MaxUpdate
FROM
ebx_r_history r
group by
r.ItemNumber,
r.SKU ) AllItems
JOIN ebx_r_history rh
ON AllItems.ItemNumber = rh.ItemNumber
AND AllItems.SKU = rh.SKU
AND ( rh.lastUpdate = AllItems.MinUpdate
OR rh.lastUpdate = AllItems.MaxUpdate )
group by
AllItems.ItemNumber,
AllItems.SKU
Per another answer where you were only looking to IGNORE items within the most recent 14 days, you can just add a WHERE clause to the inner query similar via
WHERE r.LastUpdate >= CURDATE() - INTERVAL 14 DAY
If your history table has an auto-incrementing ID column, AND the respective transactions have the lastUpdate sequentially stamped, such as when they are added and not modified by any other operation, then you could just apply similar but MIN/MAX of the ID column, then join back TWICE on the ID and just each row ONCE such as...
SELECT
AllItems.ItemNumber,
AllItems.SKU,
rhMin.LastUpdate as MinUpdate,
rhMin.QuantitySold as MinSold,
rhMax.LastUpdate as MaxUpdate,
rhMax.QuantitySold as MaxSold
from
( SELECT
r.ItemNumber,
r.SKU,
MIN( r.AutoIncrementColumn ) as MinAutoID,
MAX( r.AutoIncrementColumn ) as MaxAutoID
FROM
ebx_r_history r
group by
r.ItemNumber,
r.SKU ) AllItems
JOIN ebx_r_history rhMin
ON AllItems.MinAutoID = rhMin.AutoIncrementColumn
JOIN ebx_r_history rhMax
ON AllItems.MaxAutoID = rhMax.AutoIncrementColumn
order by
rhMax.LastUpdated
Try something like this:
SELECT r1.ItemNumber,
(
SELECT r.QuantitySold
FROM ebx_r_history r
WHERE r1.ItemNumber = r.ItemNumber
AND r1.SKU = r.SKU
ORDER BY r.LastUpdate ASC LIMIT 1
) AS earliestDateQty,
(
SELECT r.QuantitySold
FROM ebx_r_history r
WHERE r1.ItemNumber = r.ItemNumber
AND r1.SKU = r.SKU
ORDER BY r.LastUpdate DESC LIMIT 1
) AS latestDateQty
FROM ebx_r_history r1
GROUP BY r1.ItemNumber,r1.SKU
ORDER BY 3
You had a couple of errors. you were getting two columns inside the inner selects, and you had a couple of places where you might get the error for ambiguous column name.
sqlFiddle here
SELECT T1.ItemNumber,
T1.SKU,
T1.Old_QuantitySold,
T1.Old_LastUpdate,
T2.New_QuantitySold,
T2.New_LastUpdate
FROM
(SELECT itemNumber,SKU,QuantitySold as Old_QuantitySold,LastUpdate as Old_LastUpdate
FROM ebx_r_history r
WHERE NOT EXISTS (SELECT 1 FROM ebx_r_history e
WHERE e.itemNumber = r.itemNumber AND e.SKU = r.SKU
AND e.LastUpdate < r.LastUpdate)
)T1
LEFT JOIN
(SELECT itemNumber,SKU,QuantitySold as New_QuantitySold,LastUpdate as New_LastUpdate
FROM ebx_r_history r
WHERE NOT EXISTS (SELECT 1 FROM ebx_r_history e
WHERE e.itemNumber = r.itemNumber AND e.SKU = r.SKU
AND e.LastUpdate > r.LastUpdate)
)T2 ON (T2.itemNumber = T1.itemNumber AND T2.SKU = T1.SKU)
WHERE T1.Old_LastUpdate >= CURDATE() - INTERVAL 14 DAY
AND T2.New_LastUpdate >= CURDATE() - INTERVAL 14 DAY
ORDER BY T2.New_LastUpdate;
you can do left join or inner join it's up to you, since T1 will always get earliest records and T2 will always get latest records for the ItemNumber,SKU grouping.
UPDATED TO IGNORE DATA OLDER THAN 14 DAYS
SELECT T1.ItemNumber,
T1.SKU,
T1.Old_QuantitySold,
T1.Old_LastUpdate,
T2.New_QuantitySold,
T2.New_LastUpdate
FROM
(SELECT itemNumber,SKU,QuantitySold as Old_QuantitySold,LastUpdate as Old_LastUpdate
FROM ebx_r_history r
WHERE LastUpdate >= CURDATE() - INTERVAL 14 DAY
AND NOT EXISTS (SELECT 1 FROM ebx_r_history e
WHERE e.itemNumber = r.itemNumber AND e.SKU = r.SKU
AND e.LastUpdate >= CURDATE() - INTERVAL 14 DAY
AND e.LastUpdate < r.LastUpdate)
)T1
LEFT JOIN
(SELECT itemNumber,SKU,QuantitySold as New_QuantitySold,LastUpdate as New_LastUpdate
FROM ebx_r_history r
WHERE LastUpdate >= CURDATE() - INTERVAL 14 DAY
AND NOT EXISTS (SELECT 1 FROM ebx_r_history e
WHERE e.itemNumber = r.itemNumber AND e.SKU = r.SKU
AND e.LastUpdate >= CURDATE() - INTERVAL 14 DAY
AND e.LastUpdate > r.LastUpdate)
)T2 ON (T2.itemNumber = T1.itemNumber AND T2.SKU = T1.SKU)
ORDER BY T2.New_LastUpdate;
ignore data older than 14 days sqlFiddle here
If you want to use exact time (14 days ago), you can replace occurences of CURDATE() with NOW()

How to merge the result of this 2 queries in mysql server

I am actually stuck in merging the result of this two queries:
first query:
SELECT c.code, c.name, pc.sku, pc.cat_code, pp.title
FROM `cat_parent` cp, cat c, prod_cat pc, products pp
WHERE c.code = cp.cat_code
AND cp.cat_code = pc.cat_code
AND pp.sku = pc.sku
AND cp.parent_code = 01110
AND hide =0
The result I get is:
Second query:
SELECT `sku` , `update_date` , `description` , count( * ) AS total_sold
FROM `orderline`
WHERE `update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( sku, 7 )
ORDER BY total_sold DESC
The result:
The question I want to ask that how can I get the result by filtering the sku available in both tables.
Just bit confused on that part....any ideas will be appreciated.
This is only part of the data. there is heaps of data. Yes, I want to merge the both tables and want to find the common sku available in both tables.
My expected result will be sku, title, total sold.
Thanks, anyway I managed to get around to get the result.
My final query:
SELECT * FROM (
SELECT sku , update_date , description FROM orderline WHERE
update_date >= '2012-03-06' AND update_date <= '2012-03-07' )g
JOIN (
SELECT c.code, c.name, pc.sku, pc.cat_code FROM cat_parent cp, cat
c, prod_cat pc, products pp WHERE c.code = cp.cat_code AND cp.cat_code
= pc.cat_code AND pp.sku = pc.sku AND cp.parent_code =01110 AND hide =0 )p ON left( g.sku, 7 ) = left( p.sku, 7 )
Something like this -
SELECT
`c`.`code`, `c`.`name`, `pc`.`sku`, `pc`.`cat_code`, `pp.title`,
`ol`.`sku`, `ol`.`update_date`, `ol`.`description`, COUNT(*) AS `total_sold`
FROM `cat_parent` `cp`
INNER JOIN `cat` `c`
ON `c`.`code` = `cp`.`cat_code`
INNER JOIN `prod_cat` `pc`
ON `cp`.`cat_code` = `pc`.`cat_code`
INNER JOIN `products` `pp`
ON `pp`.`sku` = `pc`.`sku`
INNER JOIN `orderline` `ol`
ON LEFT(`pc`.`sku`, 7) = LEFT(`ol`.`sku`, 7)
WHERE `cp`.`parent_code` = 01110
AND `hide` = 0
AND `ol`.`update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `ol`.`update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( `ol`.`sku`, 7 )
ORDER BY `total_sold` DESC