How to achieve default value if column value is NULL? - mysql

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;

Related

Conditional table updates

Consider the following table.
myTable
+----+-----------+------------------------------------+
| Id | responseA | responseB |
+----+-----------+------------------------------------+
| 1 | | {"foo":"bar","lvl2":{"key":"val"}} |
+----+-----------+------------------------------------+
where:
Id, INT (11) PRIMARY
responseA, TEXT utf8_unicode_ci
responseB, TEXT utf8_unicode_ci
Let's say that I want to conditionally update the table with some outside data. The conditions are:
• if there's nothing in responseA, populate it with the outside data, otherwise
• if there is something in responseA, leave it as it is, and populate responseB with the outside data
I was pretty much convinced that I could just do this to get what I want:
UPDATE myTable
SET
responseA = IF(TRIM(responseA) = '','foo',TRIM(responseA)),
responseB = IF(TRIM(responseA) != '','foo',TRIM(responseB))
WHERE Id = 1
However, this updates both responseA and responseB to the same value - foo, making the table:
myTable
+----+-----------+-----------+
| Id | responseA | responseB |
+----+-----------+-----------+
| 1 | foo | foo |
+----+-----------+-----------+
I was expecting my table to look like this after the update:
myTable
+----+-----------+------------------------------------+
| Id | responseA | responseB |
+----+-----------+------------------------------------+
| 1 | foo | {"foo":"bar","lvl2":{"key":"val"}} |
+----+-----------+------------------------------------+
What am I misunderstanding, and how can I achieve this conditional update? Do the updates happen sequentially? If so, I guess that would explain why both of the fields are updated.
UPDATE TABLE
SET responseA = CASE WHEN responseA IS NULL
THEN #data
ELSE responseA
END,
responseB = CASE WHEN responseA IS NULL
THEN responseB
ELSE #data
END
;
here your changed query
UPDATE myTable
SET
responseB = IF(TRIM(responseA) != '','foo',TRIM(responseB)),
responseA = IF(TRIM(responseA) = '','foo',TRIM(responseA))
WHERE Id = 1
It seems the value of responseA is changed before the IF() for responseB is evaluated.
One possible solution is to do a simple UPDATE:
UPDATE mytable SET responseA = ? WHERE id = 1
Then adjust the columns in a trigger, where you have access to both the original and the new value of the columns:
CREATE TRIGGER t BEFORE UPDATE ON mytable
FOR EACH ROW BEGIN
IF TRIM(OLD.responseA) != '' THEN
SET NEW.responseB = NEW.responseA;
SET NEW.responseA = OLD.responseA;
END IF;
END
(I have not tested this.)
I am also assuming that your test for '' (empty string) instead of NULL is deliberate, and that you know that NULL is not the same as ''.
The key point in the UPDATE statement is that you should update first the column responseB, so that column responseA retains its original value which can be checked again when you try to update it:
UPDATE myTable
SET responseB = CASE WHEN TRIM(responseA) = '' THEN responseB ELSE 'foo' END,
responseA = CASE WHEN TRIM(responseA) = '' THEN 'foo' ELSE responseA END
WHERE Id = 1;

SELECT count(*) with where produces weird values

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 :)

Joining DISTINCT values from one table to Another

I have 7 Tables with the following structures:
tbl_Trucks | tbl_Driver | tbl_Clients
-----------------------|-----------------------------|--------------------
tr_ID - int | dr_ID - int | cl_ID - int
tr_Name - varchar(50) | dr_LName - varchar(50) | cl_Name - varchar(50)
| dr_FName - varchar(50) |
| dr_MName - varchar(50) |
tbl_ExpenseHead | tbl_ExpenseDiesels
---------------------------------|---------------------------
eh_ID - int | dsl_ID - int
eh_DateAdded - date | dsl_amt - float
eh_RouteStart - varchar(50) | dsl_Ltrs - float
eh_RouteEnd - varchar(50) | eh_ID - int
cl_ID - int |
dr_ID - int |
tr_ID - int |
eh_Status - varchar(50) |
eh_ERnumber - varchar(50) |
eh_InvoiceNumber - varchar(50) |
tbl_ExpenseTotal | tbl_Helpers
---------------------------------|---------------------------
tot_ID - int | help_ID - int
tot_OverallExpense- date | help_FName - varchar(50)
eh_ID - int | help_MName - varchar(50)
| help_LName - varchar(50)
| eh_ID - int
currently have this query
SELECT
h.eh_DateAdded as [TRIP_DATE],
t.tr_Name as [TRUCK_NAME],
d.dr_LName + ', ' + d.dr_FName + ' ' + d.dr_MName as DRIVER,
c.cl_Name as CLIENT,
h.eh_RouteStart + ' to ' + h.eh_RouteEnd as TRIP,
h.eh_InvoiceNumber as [INVOICE_NUMBER],
h.eh_ERnumber as [ER_NUMBER],
SUM(dsl.dsl_amt) as [DIESEL_AMOUNT],
SUM(dsl.dsl_Ltrs) as [DIESEL_LITERS],
tot.tot_OverallExpense as EXPENSE
FROM tbl_ExpenseHead h INNER JOIN
tbl_Trucks t ON h.tr_ID = t.tr_ID INNER JOIN
tbl_Driver d ON h.dr_ID = d.dr_ID INNER JOIN
tbl_Clients c ON h.cl_ID = c.cl_ID INNER JOIN
tbl_ExpDiesels dsl ON h.eh_ID = dsl.eh_ID INNER JOIN
tbl_ExpenseTotal tot ON h.eh_ID = tot.eh_ID
WHERE h.eh_Status = 'APPROVED'
GROUP BY
h.eh_DateAdded,
t.tr_Name,
d.dr_LName,
d.dr_FName,
d.dr_MName,
c.cl_Name,
h.eh_RouteStart,
h.eh_RouteEnd,
h.eh_InvoiceNumber,
h.eh_ERnumber,
dsl.dsl_amt,
dsl.dsl_Ltrs,
tot.tot_OverallExpense
that outputs a table like this
as you can see, the helpers are not in the table. Given that i have tbl_Helpers populated with values like this
i want the first table to turn out something like this
i want to show the helpers for each line and if it happens to have less than 2 helpers then it would be just left blank.. or NULL. I'm trying some codes here and i'm wondering if there's quick way around this. Helpers won't exceed to 2 since i restrict the user from doing so.
I tried using DISTINCT in tbl_Helpers to get each different helpers and filter them with their eh_ID's but i don't know how to get them attached to make it turn out like the third table
Your first problem is you can't decide which helper should be #1 and which should be #2. So first let's assign them a number.
Next, let's join them to your ExpenseHead:
WITH myHelpers AS (
SELECT eh_ID
, help_ID
, RANK() OVER (PARTITION BY eh_IDORDER BY help_ID) helperOrder
FROM tbl_Helpers
)
SELECT h.eh_ID
, hlp1.help_ID AS help1_ID
, hlp2.help_ID AS help2_ID
FROM tbl_ExpenseHead h LEFT JOIN
myHelpers hlp2 ON h.eh_ID = hlp2.eh_ID AND hlp2.helperOrder = 2 LEFT JOIN
myHelpers hlp1 ON h.eh_ID = hlp1.eh_ID AND hlp1.helperOrder = 1 AND hlp2.help_ID IS NOT NULL
Think of the WITH-statement as a temporary table which exists for the duration of the query, it's called a CTE.
Notice the use of LEFT JOIN since we don't know whether there are 2 helpers.
Notice that I only select hlp1 in case hlp2.help_ID IS NOT NULL, it's either 2 helpers or none.
Based on your example, I think you'll be able to apply this to your query.
Good luck!

Is there any diference between "!= NULL" and "IS NOT NULL" in MySQL?

Is there any difference between using "!= NULL" and using "IS NOT NULL"?
For example:
SELECT * FROM tbl_example WHERE a_field IS NOT NULL
and
SELECT * FROM tbl_example WHERE a_field != NULL
Yes, there is. != does not work properly with NULL1:
mysql> SELECT 1 != NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 != NULL | 1 IS NOT NULL |
+-----------+---------------+
| NULL | 1 |
+-----------+---------------+
1 row in set (0.00 sec)
BTW: != is not valid SQL, you should use the diamond operator <>.
1 In fact no comparison, except IS and IS NOT works.
You shouldn't compare values to null, becouse efect of this operation isn't true neither false - it's always unknown.
To check is value null, you should always use is null

Substring reurns a number value instead of varchar

$query = mysql_query(SELECT * FROM test WHERE SUBSTRING(date,0,4)="1392") //for example 1392
echo query['name'];
i want to get 4 first character and check its equal with 1392 or not .
but its return 1054 my column name type is varchar and i have no idea about this.
MySQL count char from 1, not from 0 as php.
try
SUBSTRING(date,1,4)="1392"
or if you want the year
YEAR(date)="1392"
http://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_substring
EDIT test exemple
CREATE TABLE babak (name VARCHAR(20) NOT NULL, date VARCHAR(10) NOT NULL);
INSERT INTO babak SELECT 'test', '1391/11/11';
INSERT INTO babak SELECT 'correct', '1932/11/11';
SELECT * FROM babak WHERE YEAR(date) = 1932;
+---------+------------+
| name | date |
+---------+------------+
| correct | 1932/11/11 |
+---------+------------+
SELECT * FROM babak WHERE SUBSTRING(date, 1, 4) = 1932;
+---------+------------+
| name | date |
+---------+------------+
| correct | 1932/11/11 |
+---------+------------+
So your date is in varchar with the format yyyy/MM/dd, try this one:
SELECT *
FROM test
WHERE SUBSTRING(`date`,1,4) = '1932'
CLICK HERE FOR DEMO
mysql_query only returns a resource, you need to use that resource to fetch the result
$resource = mysql_query('SELECT * FROM test WHERE SUBSTRING(date,1,4)="1392"')
$result = mysql_fetch_assoc($resource);
echo $result['name'];