It seems when I am trying to make a query to get the users transaction sum, it does not return the proper value until I remove the filter on code, what is even more interesting is the filter on the bar code following works perfectly fine, it seems maybe there is an inconsistency between both the subqueries in the WHERE clause?
Explanation:
With the below query, when I remove the and code != "foo" AND code !="foobar" from the query, it returns the correct value, but I also tried changing it to code = "foo" or code = "foobar" to check if any of the results had these codes, and it returns null when I do this.
SELECT SUM(t.amount)
FROM transactions t
WHERE `t`.`deleted_at` IS NULL
AND `t`.`user_id` = 80
AND `t`.`user_id` IS NOT NULL
AND `manually_deleted_at` IS NULL
AND
(SELECT count(*)
FROM `transaction_subcategories` s
WHERE `t`.`transaction_subcategory_id` = `s`.`id`
AND `code` != "foo"
AND `code` != "foobar"
AND
(SELECT count(*)
FROM `transaction_categories` c
INNER JOIN `transaction_categories_transaction_subcategories` sc ON `c`.`id` = `sc`.`transaction_category_id`
WHERE `sc`.`transaction_subcategory_id` = `s`.`id`
AND `code` = "bar") >= 1) >= 1
AND `posted_date` BETWEEN "2016-04-01 00:00:00.000000" AND "2017-03-31 23:59:59.000000"
AND `parent_id` = 0;
While I do realize this is a mysql query issue, the laravel ORM code is a bit cleaner:
$income_transactions = \Auth::user ()->transactions ()
->notManuallyDeleted()
->whereHas('transactionSubcategory', function ($query) {
$query
->where('code', '!=', 'foo')
->where('code', '!=', 'foobar')
->whereHas('transactionCategories', function ($query2){
$query2->where('code', '=', 'bar');
});
})
->whereBetween ( 'posted_date', [$from,$to])
->where('parent_id', '=', 0)
->get ();
Update
Not sure if this helps, but I did a query to see which subcategories it is returning with the WHERE clause and it returns only ones where the code is NULL
mysql> SELECT * FROM transaction_subcategories WHERE id in ('1125', '630', '1395') AND code is null;
+------+-----------------------------------+------+---------+
| id | name | code | user_id |
+------+-----------------------------------+------+---------+
| 630 | foo | NULL | 80 |
| 1125 | foo | NULL | 80 |
| 1395 | foo | NULL | 80 |
+------+-----------------------------------+------+---------+
Update 2 Turns out it is the WHERE doing it, it seems that NULL values won't be compared against a string, in other words if I do a WHERE on a column that has nulls, the null value rows will disappear
Answer Turns out adding OR code is null in a group in the WHERE clause was all I needed. Closed :)
Related
I have code for my filter. It worked well until I add new product in my database. I found the problem, but dont know what to do with that.
I have parameters "alc_min" and "alc_max" in my filter. I get these from crawling all products. After I send this filter, I fire this code:
$meta_query = array();
$b = "alc_min";
$c = "alc_max";
if (isset ( $data [$b] ) && isset ( $data [$c] )) {
$compare = "BETWEEN";
$a = array (
'key' => "alc",
'value' => array (
$data [$b],
$data [$c]
),
'compare' => $compare
);
array_push ( $meta_query, $a );
}
$items = new WP_Query ( array (
'post_type' => $type,
'posts_per_page' => $posts_per_page,
'order' => $order,
'meta_key' => $orderkey,
'orderby' => $orderby,
'post_status' => 'publish',
'meta_query' => $meta_query,
'paged' => $paged
) );
Until now, it worked well. No I add new product with "alc" <10 and I found, that if I have "alc_min" and "alc_max" <10 or >10, it is ok. But if "alc_min" is <10 and "alc_max" >10 I get no results at all.
Does anyone any idea what to check or fix?
After the clarification, I've suspected that the reason why selecting "alc_min" = 7 and "alc_max" = 13 doesn't yield any result is because of the column datatype. Consider this example:
CREATE TABLE table1 (
alc VARCHAR(50));
INSERT INTO table1 VALUES
('7'),
('9'),
('11'),
('13');
The table above is created with alc column datatype as VARCHAR instead of INTEGER (or numeric datatype). I've tested that running either one of the query below:
SELECT * FROM table1 WHERE alc BETWEEN '7' AND '9';
SELECT * FROM table1 WHERE alc BETWEEN '11' AND '13';
will return the expected result. However, with this query:
SELECT * FROM table1 WHERE alc BETWEEN '7' AND '13';
yields no result. This is because the values are treated as string instead of numbers and when that happens, 1 is always smaller than 7. See below what happen you run select query with order by on the data set above:
SELECT * FROM table1 ORDER BY alc;
+-----+
| alc |
+-----+
| 11 |
| 13 |
| 7 |
| 9 |
+-----+
As you can see, since the data is treated as string (according to the column datatype), then you could imagine this in alphabetical form as the following:
+-----+--------------+
| alc | alphabetical |
+-----+--------------+
| 11 | AA |
| 13 | AC |
| 7 | G |
| 9 | I |
+-----+--------------+
So, the condition of BETWEEN '7' AND '13' becomes BETWEEN 'G' AND 'AC'; which doesn't really make sense. And if you change to BETWEEN '11' AND '9' you'll get the correct result but that made the query even more confusing and not making sense at all.
Now, I've discovered that there are at least 3 workaround/solution for this:
One of the oldest way I can think of is by adding +0 to the column in the query. I didn't find any official docs about this but I assume that doing this will change the data value to numeric in the query:
SELECT * FROM table1
WHERE alc+0 BETWEEN '7' AND '13';
This is probably the same as above is just that I'm not sure if this is version specific or not. It turns out that in my testing, if you didn't wrap the searched value in quotes, you'll get the result as if the data is numeric:
SELECT * FROM table1
WHERE alc BETWEEN 7 AND 13;
This require a change of column datatype but afterwards any of the query with or without quotes on the searched value should work:
ALTER TABLE table1 CHANGE alc alc INT;
I hope that this is true and the issue is really about column datatype. As far as I know, this is the closest thing to what your situation is that I had experience with.
Here's a fiddle for reference
Basicly this is my mysql query:
select distinct(shipment_tag) from ir_shipment_registry where shipment_id = '2020111'
and the result set:
| shipment_tag |
+--------------+
| Truck |
| Equipment |
| |
How can I concat the two result set into string so that i can assign it to a variable? I tried
SET #purchasetype = (select distinct(shipment_tag) from ir_shipment_registry where shipment_id = '2020111')
but it returns and error says: Subquery returns more than 1 row.
I want something in my variable like : #purchasetype = "Truck, Equipment".
Perhaps use GROUP_CONCAT here:
SET #purchasetype = (SELECT GROUP_CONCAT(shipment_tag SEPARATOR ', ') FROM ir_shipment_registry WHERE shipment_id = '2020111');
I have a table and its data are mentioned below :
id | function
1 | current_date
2 | UUID()
3 | RAND()
Structure of the table is
id int, function varchar(50)
Query : select * from func_table;
My excepted result is
id | function
1 | 2020-08-24
2 | 70d6cffc-ae01-11ea-80ca-c11529136ae3630
3 | 0.982584554752
Thanks in advance.
You can use a giant case expression:
select (case when function = 'current_date' then cast(current_date as char)
when function = 'uuid()' then cast(uuid as char)
when function = 'rand()' then cast(rand as char)
end) as value
If you actually want to evaluate the function directly, then you probably have a problem with your data model. SQL does not directly support such functionality.
I know that Error 1690 is nothing new in mysql but after searching for solution here i just gave up. So here I go, the error I get is:
BIGINT UNSIGNED value is out of range in '(v_from#10 - p_from#1)'
The problem is, I do not have any substraction in my query... honestly i even removed "-" from DATE_FORMAT!
My query is:
SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';
select count(distinct user_id) as 'event_count_dis',count(user_id) as 'event_count',DATE_FORMAT(event_time,'%Y%m') as 'data',
getEventCourse(event_desc) as 'Name'
from sys_events c where DATE_FORMAT(event_time,'%Y%m') like '201809'
and event_type in ('Clicked')
group by getEventCourse(event_desc)
order by count(distinct user_id) desc Limit 20
Function getEventCourse(event_desc) works perfectly as it is very simple.
When i dissect this query and tested every part of it separately, everything worked fine... and I just gave up... Maybe some of you have any idea what's wrong? or at least can tell me what the heck is
'(v_from#10 - p_from#1)'
Function getEventCourse:
BEGIN
DECLARE courseName varchar(100);
IF(LOCATE('cid',description) > 0) THEN
SET courseName = (Select courses_name from sys_courses where courses_id = test_baza.extract_json_value(description,'cid'));
ELSEIF(LOCATE('course_id',description) > 0) THEN
SET courseName = (Select courses_name from sys_courses where courses_id = test_baza.extract_json_value(description,'course_id'));
ELSE
SET courseName = null;
END IF;
RETURN courseName;
END
sys_events:
event_id | event_time | event_desc | event_type | user_id
1537919 | 2018-10-12 | {"course_id":"386","element_id":"498"}| Clicked | 1235
Edit:
Ok, it seems that problem appears in "group by" section.
I want to retrieve some column values from table with these conditions.
If value is NULL (or) Empty String , return some user defined value
If not above condition , return it's value.
How can I figure it out ?
Here is my Table query..
CREATE TABLE AUCTION_CAR_BID(
bid_seq bigint NOT NULL AUTO_INCREMENT,
auction_car_seq bigint NOT NULL,
bid_group_seq bigint NOT NULL,
bid_price int DEFAULT 0 NOT NULL,
over_bid_price int DEFAULT -1 NOT NULL,
result_id int DEFAULT 0 NOT NULL,
remark varchar(500),
PRIMARY KEY (bid_seq))
ENGINE = InnoDB DEFAULT CHARACTER SET utf8;
Here is my efforted codes to get it..
SELECT
COALESCE(OVER_BID_PRICE, -1)
FROM
AUCTION_CAR_BID
WHERE
BID_SEQ = 2354435345;
Another :
SELECT
CASE
WHEN OVER_BID_PRICE IS NULL
OR TRIM(OVER_BID_PRICE) = '' THEN -1
ELSE OVER_BID_PRICE
END OVER_BID_PRICE
FROM
AUCTION_CAR_BID
WHERE
BID_SEQ = 2354435345;
But I always get empty String value(not -1) if given id is not in my table.
Any suggestions would be really appreciated !
If you write this:
SELECT
COALESCE(OVER_BID_PRICE, -1)
FROM
AUCTION_CAR_BID
WHERE
BID_SEQ = 2354435345;
The results can be two types.
First result: Your query no returns rows! Your WHERE condition is unsatisfact so you'll read NULL
Second result: Your query returns rows but the value of your field is NULL, your COALESCE works fine in this case
To resolve you can try this:
SELECT COALESCE(
(SELECT
COALESCE(OVER_BID_PRICE, -1)
FROM AUCTION_CAR_BID
WHERE BID_SEQ = 2354435345)
,-1);
Tell me if it's OK
How about this:
select
case when price is null or id <> 1
then -1
else price
end price
from mytable
DROP TABLE prices;
CREATE TABLE prices (price_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,price INT NULL);
INSERT INTO prices (price) VALUES (' '),(''),(NULL);
SELECT * FROM prices;
+----------+-------+
| price_id | price |
+----------+-------+
| 1 | 0 |
| 2 | 0 |
| 3 | NULL |
+----------+-------+
SELECT price_id,COALESCE(price,-1) price FROM prices;
+----------+-------+
| price_id | price |
+----------+-------+
| 1 | 0 |
| 2 | 0 |
| 3 | -1 |
+----------+-------+
If there's no row for USER_SEQ = 2354435345 in your table there's no row returned. But aggregate functions always return a row even if the result is empty :-)
SELECT
COALESCE(MIN(OVER_BID_PRICE), -1)
FROM
USER_PARAM
WHERE
USER_SEQ = 2354435345;