SELECT DEFAULT returns NULL - mysql

I want to return two defaults column values even if the table has no records. I'm using the following query (thanks to How to SELECT DEFAULT value of a field):
SELECT DEFAULT(membership_credits) AS membership_credits,
DEFAULT(product_credits) AS product_credits
FROM (SELECT 1) AS dummy LEFT JOIN Users ON True LIMIT 1
But instead of the default values, I'm getting NULL:
membership_credits product_credits
NULL NULL
What's the problem?
EDIT:
Adding the table schema as suggested in a comment:
CREATE TABLE Users (
user_id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
user_login VARCHAR(40) NOT NULL UNIQUE,
user_name VARCHAR(100) NOT NULL,
user_email VARCHAR(254) NOT NULL UNIQUE,
user_telephone VARCHAR(100) NOT NULL,
user_password VARCHAR(64) NOT NULL,
user_address VARCHAR(255) NOT NULL,
user_postal_code VARCHAR(100) NOT NULL,
user_district VARCHAR(100) NOT NULL,
user_country VARCHAR(100) NOT NULL,
user_tax_number VARCHAR(20) NOT NULL,
user_billing_email VARCHAR(254) NOT NULL,
company_description TEXT,
company_history TEXT,
company_products TEXT,
public_contact BINARY(1) NOT NULL,
user_active BINARY(1) NOT NULL DEFAULT '0',
user_key VARCHAR(255) NOT NULL,
user_registered TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
unread_messages INT UNSIGNED DEFAULT 0,
membership_credits INT UNSIGNED NOT NULL DEFAULT 0,
product_credits INT UNSIGNED NOT NULL DEFAULT 0
) ENGINE INNODB CHARACTER SET utf8 COLLATE utf8_general_ci;

It all depends on if your columns allow NULL or not.
If NULL allow, a query like the following will be useful, so the table does not have records:
SELECT
DEFAULT(`membership_credits`) `membership_credits`,
DEFAULT(`product_credits`) `product_credits`
FROM (SELECT 1) `dummy`
LEFT JOIN `users` ON TRUE
LIMIT 1;
SQL Fiddle demo
If not allow NULL, and the table has no record, you will get a NULL to the query above. In this case would require a query like:
SELECT
DEFAULT(`membership_credits`) `membership_credits`,
DEFAULT(`product_credits`) `product_credits`
FROM (SELECT *, COUNT(0)
FROM `users`) `users`;
SQL Fiddle demo
UPDATE
Be careful in MySQL >= 5.6 does not operate in the same way and NULL values ​​are obtained.
SQL Fiddle demo

Try this Query
SELECT COLUMN_DEFAULT FROM information_schema.columns
WHERE TABLE_SCHEMA = 'your_database_name' AND
TABLE_NAME = 'your_table_name' AND COLUMN_NAME = 'your_column_name';
In Your case
SELECT COLUMN_DEFAULT FROM information_schema.columns
WHERE TABLE_SCHEMA = 'test' AND
TABLE_NAME = 'users' AND
COLUMN_NAME in ('membership_credits','product_credits');

if you use following query to create table
CREATE TABLE `users` (
`user_id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_login` VARCHAR(40) NOT NULL,
`user_name` VARCHAR(100) NOT NULL,
`user_email` VARCHAR(254) NOT NULL,
`user_telephone` VARCHAR(100) NOT NULL,
`user_password` VARCHAR(64) NOT NULL,
`user_address` VARCHAR(255) NOT NULL,
`user_postal_code` VARCHAR(100) NOT NULL,
`user_district` VARCHAR(100) NOT NULL,
`user_country` VARCHAR(100) NOT NULL,
`user_tax_number` VARCHAR(20) NOT NULL,
`user_billing_email` VARCHAR(254) NOT NULL,
`company_description` TEXT NULL,
`company_history` TEXT NULL,
`company_products` TEXT NULL,
`public_contact` BINARY(1) NOT NULL,
`user_active` BINARY(1) NOT NULL DEFAULT '0',
`user_key` VARCHAR(255) NOT NULL,
`user_registered` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`unread_messages` INT(10) UNSIGNED NULL DEFAULT '0',
`membership_credits` INT(10) UNSIGNED NULL DEFAULT '0',
`product_credits` INT(10) UNSIGNED NULL DEFAULT '0',
PRIMARY KEY (`user_id`),
UNIQUE INDEX `user_login` (`user_login`),
UNIQUE INDEX `user_email` (`user_email`)
)
And use below query to get default values
SELECT if(DEFAULT(membership_credits) is null,0,
DEFAULT(membership_credits))AS membership_credits,if(DEFAULT(product_credits)
is null,0,DEFAULT(product_credits) )AS product_credits FROM
(SELECT 1) AS dummy LEFT JOIN Users ON True LIMIT 1
You must note that in the above create query membership_credits and product_credits modified to allow null

Use below query :
SELECT
IF(COUNT(user_id) = 0,
DEFAULT( membership_credits),
membership_credits) AS membership_credits,
IF(COUNT(user_id) = 0,
DEFAULT( product_credits),
product_credits) AS product_credits FROM
(SELECT 1) AS dummy LEFT JOIN
Users ON TRUE

Use the below query :
SELECT
IF(COUNT(user_id) = 0,
DEFAULT( membership_credits),
membership_credits) AS membership_credits,
IF(COUNT(user_id) = 0,
DEFAULT( product_credits),
product_credits) AS product_credits
FROM
(SELECT 1) AS dummy
LEFT JOIN
Users ON TRUE

Related

I want two tables calculate

I want to add and calculate using data from 2 tables.
The results I want are as follows.
However, if I send a query as follows:
SELECT COUNT(IF(treatment_fees_check_division = 'test',
treatment_fees_check_division, NULL)) AS COUNT, SUM(CASE WHEN
treatment_fees_check_division = 'test' THEN treatment_fees_difference
END) + SUM(advenced_amount) AS if_treatment_fees_check_division,
SUM(advenced_amount) AS sum_init_amount FROM ( SELECT
treatment_fees_check_division, treatment_fees_difference,
advenced_amount FROM hospital_payment_data, advenced_payment WHERE
hospital_payment_data.id = advenced_payment.chart_num ) AS a
These results occur.
create table of hospital_payment_data and data
CREATE TABLE `hospital_payment_data` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`date` TIMESTAMP NOT NULL DEFAULT current_timestamp(),
`chart_num` INT(11) NOT NULL ,
`chart_name` VARCHAR(50) NOT NULL,
`visit` DATE NOT NULL,
`non_payment_sales` VARCHAR(50) NOT NULL,
`total_medical_bills` VARCHAR(50) NOT NULL,
`total_amount` VARCHAR(50) NOT NULL,
`amount_asked` VARCHAR(50) NOT NULL,
`medical_bills_payment` VARCHAR(50) NOT NULL,
`personal_liability_amount` VARCHAR(50) NOT NULL,
`non_payment` VARCHAR(50) NOT NULL,
`insurance_division` VARCHAR(50) NOT NULL,
`division` VARCHAR(50) NOT NULL,
`cash_amount_received` VARCHAR(50) NOT NULL,
`cash_receipt` VARCHAR(50) NOT NULL,
`cash_receipt_non_payment` VARCHAR(50) NOT NULL,
`cash_receipt_payment` VARCHAR(50) NOT NULL,
`card_amount_received` VARCHAR(50) NOT NULL,
`card_non_payment` VARCHAR(50) NOT NULL,
`card_payment` VARCHAR(50) NOT NULL,
`medical_bills_check` VARCHAR(50) NOT NULL,
`medical_bills_check_modify` VARCHAR(50) NOT NULL DEFAULT 'N',
`treatment_fees_difference` VARCHAR(50) NOT NULL,
`init_amount` VARCHAR(50) NOT NULL DEFAULT '0',
`treatment_fees_check_division` VARCHAR(50) NOT NULL DEFAULT '-',
`treatment_fees_check` VARCHAR(50) NOT NULL,
`treatment_fees_check_modify` VARCHAR(50) NOT NULL DEFAULT 'N',
`treatment_fees_check_memo` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
)
COLLATE='euckr_korean_ci'
ENGINE=InnoDB
AUTO_INCREMENT=18
;
create table of advenced_payment and data
CREATE TABLE `advenced_payment` (`id` INT(11) NOT NULL AUTO_INCREMENT,
`date` TIMESTAMP NULL DEFAULT NULL,
`chart_num` VARCHAR(50) NULL DEFAULT NULL,
`chart_name` VARCHAR(50) NULL DEFAULT NULL,
`advenced_amount` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `chart_num` (`chart_num`)) COLLATE='euckr_korean_ci' ENGINE=InnoDB AUTO_INCREMENT=2 ;
How do fix my query??
You have numerous issues with you query. This won't fix your problems, but I recommend writing it as:
SELECT SUM(hpd.treatment_fees_check_division = 'test') AS COUNT,
(SUM(CASE WHEN hpd.treatment_fees_check_division = 'test' THEN hpd.treatment_fees_difference END) +
SUM(advenced_amount)
) AS if_treatment_fees_check_division,
SUM(advenced_amount) AS sum_init_amount
FROM hospital_payment_data hpd JOIN
advanced_payment ap
ON hpd.id = ap.chart_num;
This simplifies and fixes some issues:
The JOIN uses proper, explicit, standard, readable syntax. Never use commas in the FROM clause.
The subquery is utterly unnecessary and probably adversely affects performance.
All tables have table aliases.
All column references are qualified.
The condition count is much simplified using sum(<boolean>).
I note that treatment_fees_difference is a string, yet you are using SUM(). That is really, really bad.
In any case, your problem, is that one of the tables has multiple rows. It is hard to know which one but my guess is advanced_payment. The solution is to preaggregate before the JOIN:
SELECT SUM(hpd.treatment_fees_check_division = 'test') AS COUNT,
(SUM(CASE WHEN hpd.treatment_fees_check_division = 'test' THEN hpd.treatment_fees_difference END) +
SUM(ap.sum_init_amount)
) AS if_treatment_fees_check_division,
SUM(ap.sum_init_amount) AS sum_init_amount
FROM hospital_payment_data hpd JOIN
(SELECT ap.chart_num, COUNT(*) as cnt, SUM(advenced_amount) as sum_init_amount
FROM advanced_payment ap
GROUP BY ap.chart_num
) ap
ON hpd.id = ap.chart_num;

Optimize query for yii2

this query is getting the right data i want, but this is so slow and heavy on our server, with only 5417 rows of data. how would i optimize this query in query builder or yii2 framework way?
SELECT t1.id
FROM tbl_ticket t1
WHERE NOT EXISTS
( SELECT 1
FROM tbl_ticket
WHERE parent_id = t1.id
)
AND parent_id =0
UNION ALL
SELECT MAX( id )
FROM tbl_ticket
WHERE parent_id <>0
GROUP BY parent_id
ORDER BY id ASC
( SELECT t1.id
FROM tbl_ticket t1
LEFT JOIN tbl_ticket t2 ON t2.parent_id = t1.id
WHERE t2.id IS NULL
AND t1.parent_id = 0 )
UNION ALL
( SELECT MAX( id )
FROM tbl_ticket
WHERE parent_id <> 0
GROUP BY parent_id )
ORDER BY id ASC
The first SELECT seems to be finding ids that have no children and no parents. Correct?
The second SELECT seems to be finding the last sibling in each family, excluding Adam and Eve. Is that what you intended?
I added parentheses to move the ORDER BY away from the second SELECT to the entire query. Is that what you intended?
To make that query run 'fast', you need
INDEX(parent_id, id)
I assume, you already have PRIMARY KEY(id). (Please provide SHOW CREATE TABLE tbl_ticket.)
here is the table:
CREATE TABLE IF NOT EXISTS tbl_ticket (
id int(9) NOT NULL AUTO_INCREMENT,
parent_id int(11) NOT NULL,
ticket_title varchar(250) NOT NULL,
location_id varchar(250) CHARACTER SET latin1 NOT NULL,
status int(11) NOT NULL,
remarks varchar(250) CHARACTER SET latin1 NOT NULL,
r_date datetime NOT NULL,
d_date datetime NOT NULL,
hd_user_username varchar(250) CHARACTER SET latin1 NOT NULL,
hd_user_email varchar(250) CHARACTER SET latin1 NOT NULL,
description varchar(3000) NOT NULL,
attachment varchar(250) NOT NULL,
created_by varchar(250) NOT NULL,
updated_by varchar(250) NOT NULL,
room_no varchar(250) NOT NULL,
gsm varchar(250) NOT NULL,
file_mime_type varchar(250) NOT NULL,
file_original_name varchar(250) DEFAULT NULL,
file_size varchar(250) DEFAULT NULL,
file_extension varchar(250) DEFAULT NULL,
acknowledged varchar(250) DEFAULT NULL,
ip_address varchar(20) DEFAULT NULL,
hostname varchar(255) DEFAULT NULL,
useragent text,
closing_remark varchar(2048) DEFAULT NULL,
rating int(6) DEFAULT NULL,
is_student int(2) DEFAULT NULL,
installation int(1) DEFAULT NULL,
type int(1) DEFAULT NULL,
PRIMARY KEY (id),
KEY id (id),
KEY parent_id (parent_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5428 ;

sql can't figure out the query

I have three tables:
CREATE TABLE IF NOT EXISTS `contacts` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`providerId` int(10) unsigned NOT NULL DEFAULT '0',
`requestId` int(10) unsigned NOT NULL DEFAULT '0',
`status` binary(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
CREATE TABLE IF NOT EXISTS `messages` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`fromuid` int(255) NOT NULL,
`touid` int(255) NOT NULL,
`sentdt` datetime NOT NULL,
`read` tinyint(1) NOT NULL DEFAULT '0',
`readdt` datetime DEFAULT NULL,
`messagetext` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`)
)
CREATE TABLE IF NOT EXISTS `users` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`email` varchar(255) DEFAULT NULL,
`mobile` varchar(15) NOT NULL,
`password` varchar(255) NOT NULL,
`city` varchar(255) NOT NULL,
`zip` varchar(15) DEFAULT NULL,
`device` varchar(50) DEFAULT NULL,
`version` varchar(10) DEFAULT NULL,
`photo` varchar(255) DEFAULT NULL,
`created` datetime NOT NULL,
`live` enum('0','1') NOT NULL DEFAULT '1',
`authenticationTime` datetime NOT NULL,
`userKey` varchar(255) DEFAULT NULL,
`IP` varchar(50) DEFAULT NULL,
`port` int(10) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `firstname` (`mobile`,`city`,`zip`)
)
And this SQL query that finds out friends/contacts for specified user (user id 1 in this case):
SELECT u.id
,u.mobile
,u.name
,(NOW() - u.authenticationTime) AS authenticateTimeDifference
,u.IP
,f.providerid
,f.requestid
,f.status
,u.port
FROM contacts f
LEFT JOIN users u ON u.id =
IF (
f.providerid = 1
,f.requestid
,f.providerid
) WHERE (
f.providerid = 1
AND f.status = 1
)
OR f.requestid = 1
That works fine but I want to be able to also join messages table and show user's friends/contacts who have talked latest (meaning latest conversations first) with order by messages.sentdt desc option but I am unable to figure out how to do that, I tried all joins but none worked :(
Your help will be greatly appreciated. Thanks
Update
Here is sample data above query returns:
In that same resultset, I want to be able to sort based on order by messages.sentdt desc but I am not sure how to pull that in and sort resultset by latest message first
Try this:
select u.id
, u.mobile
, u.name
, (NOW() - u.authenticationTime) as authenticateTimeDifference
, u.IP
, f.providerid
, f.requestid
, f.status
, u.port
from contacts f
left join users u
on u.id = if (f.providerid = 1, f.requestid, f.providerid)
left join (select fromuid, max(sentdt) as sentdt from messages group by fromuid) m
on m.fromuid = if (f.providerid = 1, f.providerid, f.requestid)
where (f.providerid = 1 and f.status = 1)
or f.requestid = 1
order by m.sentdt

Need suggestion on optimization of MYSQL query

SELECT `tb1`.`id`
FROM `table1` as tb1
INNER JOIN `table2` as tb2 ON tb1.id = tb2.id
INNER JOIN `table3` as tb3 ON tb1.id = tb3.id
WHERE (tb1.item_id = '1')
AND (tb1.user_id = '20')
AND (tb1.type IN ('UPDATE1','UPDATE2','UPDATE3'))
AND (tb1.status = 'DELIVERED')
ORDER BY tb1.date DESC
LIMIT 100
CREATE TABLE `table1` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(11) UNSIGNED NOT NULL,
`item_id` INT(11) UNSIGNED NULL DEFAULT NULL,
`source` ENUM('CPAS','UNIQUE_KEY','BILLING_PARTNER','GAME','MERCURY') NOT NULL,
`date` DATETIME NOT NULL,
`status` ENUM('PENDING','DELIVERED','FAILED','REFUNDED') NOT NULL,
`source_transaction_id` VARCHAR(127) NULL DEFAULT NULL,
`type` ENUM('UPDATE1','UPDATE2','UPDATE3','UPDATE4') NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `table2` (
`id_p` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`id` INT(11) UNSIGNED NOT NULL,
`amount` DECIMAL(18,2) NOT NULL,
`old_balance` DECIMAL(18,2) NULL DEFAULT NULL,
`description` VARCHAR(255) NULL DEFAULT NULL,
`date` DATETIME NULL DEFAULT NULL,
`wallet_currency_id` INT(11) NULL DEFAULT NULL,
`wallet_currency_code` VARCHAR(50) NULL DEFAULT NULL,
`wallet_currency_name` VARCHAR(100) NULL DEFAULT NULL,
`type` ENUM('GAIN','SPENT') NULL DEFAULT NULL,
PRIMARY KEY (`id_p`),
INDEX `id` (`id`)
)
CREATE TABLE `table3` (
`id_p` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`id` INT(11) UNSIGNED NOT NULL,
`amount` DECIMAL(18,2) NOT NULL,
`old_balance` DECIMAL(18,2) NULL DEFAULT NULL,
`description` VARCHAR(255) NULL DEFAULT NULL,
`date` DATETIME NULL DEFAULT NULL,
`wallet_currency_id` INT(11) NULL DEFAULT NULL,
`wallet_currency_code` VARCHAR(50) NULL DEFAULT NULL,
`wallet_currency_name` VARCHAR(100) NULL DEFAULT NULL,
`type` ENUM('GAIN','SPENT') NULL DEFAULT NULL,
PRIMARY KEY (`id_p`),
INDEX `id` (`id`)
)
What optimization possible on the above query.
table1 contains more than 500000 rows, table2 and table3 can also have more than 100000 rows.
As per query for particular player and game table1 can have more than 100000 rows.
Is the above query is ok for large large tables or should I split the query in multiple queries.
NDB Engine used.
Please suggest me possible optimization.
Thanks,
Shiv
See comments above, but, at a guess, an index on (item_id,user_id,type,status) might help.

sql statement mysql notcorrect

SELECT SUBSTRING(m.own,3,4) as c , (select amphur.AMPHUR_NAME where c = SUBSTRING(m.own,3,4) ),
COUNT(* ) AS cnt
FROM MEMBER AS m
GROUP BY SUBSTRING(m.own,3,4)
order by cnt desc
sql statement mysql
what wrong with code below when i fill
(select amphur.AMPHUR_NAME where c = SUBSTRING(m.own,3,4) )
it error
CREATE TABLE IF NOT EXISTS `member` (
`idmember` int(11) NOT NULL AUTO_INCREMENT,
`own` varchar(255) DEFAULT NULL,
`Sname` varchar(255) DEFAULT NULL,
`Ssurname` varchar(255) DEFAULT NULL,
`Sex` enum('¿','¿') NOT NULL,
`Hno` varchar(255) DEFAULT NULL,
`Moo` varchar(255) DEFAULT NULL,
`tambol` varchar(200) NOT NULL,
`dateofbirth` date DEFAULT NULL,
`migratedate` date DEFAULT NULL,
`status` enum('5','4','3','2','1') DEFAULT '5',
`Unit` int(4) DEFAULT NULL,
`staff1` int(11) DEFAULT NULL,
`staff2` int(11) DEFAULT NULL,
`fathercode` varchar(30) NOT NULL,
`mathercode` varchar(30) NOT NULL,
PRIMARY KEY (`idmember`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=8994 ;
CREATE TABLE IF NOT EXISTS `amphur` (
`AMPHUR_ID` int(5) NOT NULL AUTO_INCREMENT,
`AMPHUR_CODE` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
`AMPHUR_NAME` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
`GEO_ID` int(5) NOT NULL DEFAULT '0',
`PROVINCE_ID` int(5) NOT NULL DEFAULT '0',
`province_name` varchar(80) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`AMPHUR_ID`),
KEY `province_name` (`province_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=999 ;
Your subquery is missing a From clause:
SELECT SUBSTRING(m.own,3,4) as c
, (select amphur.AMPHUR_NAME
From amphur
Where ??? = SUBSTRING(m.own,3,4) )
, COUNT(* ) AS cnt
FROM MEMBER AS m
However, how does the amphur table relate to the member table?
You cannot use aliases in the same level.
Even if you could, you are filtering on non-correlated columns in your subquery: the subquery would just return the record from amphur if there is one record, or an error if there are more.
Could you please provide some sample data and the desired recordset?
there is no "FROM" clause in your select Amphur.amphur_name