I have a query that gets a sku_product product that is sold on a precise date
SELECT stock_products.`related_warehouse_position_id`, `product_code`, `EAN_CODE`, `custom_cart_picked_up`, `warehouse`, sum(`RemainingStock`), stock_products.`time_Picked_up`
FROM `product_warehouse_position`
INNER JOIN stock_products ON product_warehouse_position.id = stock_products.related_warehouse_position_id
WHERE stock_products.time_Picked_up < '2017-10-10'
GROUP BY product_code
HAVING SUM(RemainingStock) = 0
Now i've tried with this query but the result is wrong.
I've try to make a subquery, but i need to get a time_pickedUp which is located on stock_products table.
SELECT `id` ,`product_code`, `EAN_CODE`, `custom_cart_picked_up`, `warehouse`, sum(`RemainingStock`)
FROM product_warehouse_position
WHERE product_code IN (
SELECT product_stock_sku, time_Picked_up
FROM `stock_products`
WHERE stock_products.time_Picked_up < '2017-05-01'
)
GROUP BY product_warehouse_position.product_code
HAVING SUM(product_warehouse_position.`RemainingStock`) = 0
This query return an error :
Operand should contain 1 column(s).
How to solve this problem without change the structure of this query?
If your query is correct then the only thing you need to do is remove the column time_Picked_up from the select in your inner query. You can still filter on that column in your WHERE clause.
Related
Good Day
I have the following query but I'm getting an error message 'Operand should contain 1 column(s)'
Any assistance would be greatly appreciated
UPDATE expenditure
SET BP = (
SELECT * ,
SUM(balance_provision - actual_amt_voucher) over (partition by voteid order by expenditureid) AS BalanceProvision
FROM expenditure
)
It looks like you want to update column bp with a window sum.
Your query fails because you are trying to assign a resultset (that has multiple columns) to a single column.
But even you were returning a scalar value from the subquery, this would not work, since MySQL does not allow reusing the target table of the update in a subquery.
Instead, yo can use the update ... join syntax. Assuming that expenditureid is the primary key of the table, as its name suggests, that would be:
update expenditure e
inner join (
select
expenditureid,
sum(balance_provision - actual_amt_voucher) over (partition by voteid order by expenditureid) bp
from expenditure
group by expenditureid
) e1 on e.expenditureid = e1.expenditureid
set e.bp = e1.bp
I have a query that gets data and also joins another table (A) and counts the rows in that join table (B). However if the main table (A) is empty I want the query to return nothing. However it is returning a result of null for id and date and an integer value of 0 for users instead of a null row. How do I get an empty result instead of it returning something?
Returning:
id | date | users
null | null | 0
SQL Code
SELECT
`sessions`.`id`,
`sessions`.`date`,
COUNT( sessions_users.id ) AS users
FROM
`sessions`
LEFT JOIN `sessions_users` ON `sessions`.`id` = `sessions_users`.`sessions_id`
An aggregate query without a group by clause always returns a single record, regardless of the content of the underlying result set (and even if it is empty).
But, since you have non-aggregated columns in the select clause (sessions.id and sessions.date), your query is missing a group by clause anyway. In non-ancient versions in MySQL, where sql mode ONLY_FULL_GROUP_BY is enabled by default, this is a syntax error.
Consider:
SELECT
`sessions`.`id`,
`sessions`.`date`,
COUNT( sessions_users.id ) AS users
FROM
`sessions`
LEFT JOIN `sessions_users` ON `sessions`.`id` = `sessions_users`.`sessions_id`
GROUP BY
`sessions`.`id`,
`sessions`.`date`
This will produce one record per session id and date, along with the count of matching records in sessions_users. If there are no records in sessions, the query will return an empty result set.
If I understand correctly, instead of NULL, you want something like this:
id | date | users
| | 0
If so, just simply use IFNULL() in your SELECT as such:
SELECT
IFNULL(`sessions`.`id`,' ') as id,
IFNULL(`sessions`.`date`,' ') as date,
....
There are also a few other ways to achieve this using just IF() or CASE .. but IFNULL is very straight forward.
BUT if you don't want to see any NULL and 0 values, change your LEFT JOIN to INNER JOIN and you're done.
From your description, it sounds like you want an inner join:
SELECT s.id, s.date, COUNT(*) as users
FROM sessions s JOIN
sessions_users su
ON su.id = su.sessions_id;
SELECT
outctc.year,
outctc.ctc,
outctc.gross,
(SELECT
(case when (COUNT(EMP_ID)>=1)then inrctc.ctc else outctc.ctc end)
FROM
employee_ctc inrctc
WHERE
inrctc.EMP_ID = outctc.EMP_ID
GROUP BY
inrctc.ctc,inrctc.EMP_ID)
FROM employee_ctc outctc
WHERE outctc.EMP_ID=100002
Error:
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
When you are using a subquery inside a select, It is expected to return only 1 Single row and a column. So if you think there may be multiple rows or columns, and you need them all, then you should better use a CTE or use the Subquery in the join or where part.
Or even you can simply overcome the error by putting a Top 1 in the select.
here you are getting the error because in the Group BY part, you have given 2 column, but in the join part, there is only one. So in your table employee_ctc, there may be multiple records for the EMP_ID 100002
You can either add the remaining column (inrctc.ctc) to the join or remove that from the Group by
This might work for you :
select
outctc.year,
outctc.ctc,
outctc.gross,
CASE WHEN Q.ctc IS NOT NULL
THEN Q.ctc else outctc.ctc end
from employee_ctc outctc
OUTER APPLY
(
select
CTC = SUM(inrctc.ctc)
from employee_ctc inrctc
where inrctc.EMP_ID=outctc.EMP_ID
)Q
where outctc.EMP_ID=100002
I'm trying to show staff_code, staff_name and dept_name for those who have taken one book.
Here's my query:
SELECT SM.STAFF_CODE,SM.STAFF_NAME,DM.DEPT_NAME,BT.BOOK_CODE
FROM STAFF_MASTER SM,DEPARTMENT_MASTER DM,BOOK_TRANSACTIONS BT
WHERE SM.DEPT_CODE =DM.DEPT_CODE
AND SM.STAFF_CODE = (
SELECT STAFF_CODE
FROM BOOK_TRANSACTIONS
HAVING COUNT(*) > 1
GROUP BY STAFF_CODE)
It gives the error:
single-row subquery returns more than one row.
How to solve this?
Change = to IN:
WHERE SM.STAFF_CODE IN (SELECT ...)
Because the select returns multiple values, using equals won't work, but IN returns true if any of the values in a list match. The list can be a hard-coded CSV list, or a select with one column like your query is.
That will fix the error, but you also need to remove BOOK_TRANSACTIONS from the table list and remove BOOK_CODE from the select list.
After making these changes, your query would look like this:
SELECT SM.STAFF_CODE,SM.STAFF_NAME,DM.DEPT_NAME
FROM STAFF_MASTER SM,DEPARTMENT_MASTER DM
WHERE SM.DEPT_CODE =DM.DEPT_CODE
AND SM.STAFF_CODE IN (
SELECT STAFF_CODE
FROM BOOK_TRANSACTIONS
HAVING COUNT(*) > 1
GROUP BY STAFF_CODE)
I recommend learning the modern (now over 25 year old) JOIN syntax.
I find it really annoying to be not able to get the number of rows without having to use group by. I just need to get the "Total count" that my subquery returned.
Here is what my subquery looks like:
select sales_flat_order.increment_id, sales_flat_order.created_at, sales_flat_order.status, dispatch.dispatch_date,
DATEDIFF(TO_DATE(dispatch.dispatch_date), TO_DATE(sales_flat_order.created_at)) as delay
FROM
magentodb.sales_flat_order
LEFT OUTER JOIN erpdb.dispatch
ON
sales_flat_order.increment_id == dispatch.order_num
where
TO_DATE(created_at) >= DATE_SUB(current_date(),6)
AND
TO_DATE(created_at) <= DATE_SUB(current_date(), 3)
AND
sales_flat_order.status NOT IN ('canceled', 'exchange', 'rto', 'pending_auth', 'pending_payment' ,'partial_refund','refund', 'refund_cash', 'partial_refund_cash', 'holded')
)
AS TempFiltered
Now, I add 1 extra WHERE clause in my outer query so that it returned "lesser" number of rows, let's call this column y .
I then require to take percentage of x to y(i.e number of rows returned by outer query to subquery)
I do not wan to repeat my subquery only to get count of the rows. HOw do I get it?
This is what I have so far: But ofcourse it is wrong. I can not get count of all my rows without having to exclude select columns or using them in group by. HOw do I resolve this?
SELECT tempfiltered.delay, count(*) as countOfOrders,(100*count(*))/tempfiltered.Total) over () as percentage
FROM
(
select count(*) as Total, sales_flat_order.increment_id, sales_flat_order.created_at, sales_flat_order.status, dispatch.dispatch_date,
DATEDIFF(TO_DATE(dispatch.dispatch_date), TO_DATE(sales_flat_order.created_at)) as delay
FROM
magentodb.sales_flat_order
LEFT OUTER JOIN erpdb.dispatch
ON
sales_flat_order.increment_id == dispatch.order_num
where
TO_DATE(created_at) >= DATE_SUB(current_date(),6)
AND
TO_DATE(created_at) <= DATE_SUB(current_date(), 3)
AND
sales_flat_order.status NOT IN ('canceled', 'exchange', 'rto', 'pending_auth', 'pending_payment' ,'partial_refund','refund', 'refund_cash', 'partial_refund_cash', 'holded')
)
AS TempFiltered
Where
DATEDIFF(TO_DATE(TempFiltered.dispatch_date), TO_DATE(TempFiltered.created_at)) > 1
GROUP BY tempfiltered.delay
ORDER BY tempfiltered.delay
You could change the subquery into a SELECT INTO query, and put the data in a temporary table, and use that in the main query, and separately just select count(*) of that temporary table. That should pretty much satisfy your requirement.