Optimize query for yii2 - mysql

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 ;

Related

How to optimize MySQL query with multiple identical subqueries and multiple grouping

Problem statement
The two identical sub-queries (i.e., "a" and "b") are used to derive sub-query "n" which I further aggregate to get the final result. The response time of the query is not optimal, can anyone share some ideas to help optimize? I tried to comebine "a" and "b" as well as "a" and "n" but neither turns out to be dead ends per my knowledge...
select n.businessLiaision,
n.channel,
n.name,
n.dt,
n.ifNew,
count(n.productRowId),
sum(n.totalQty),
sum(n.totalAmount)
from ( select a.productRowId,
a.name,
a.rowId,
a.dt,
a.businessLiaision,
a.channel,
a.ct,
a.totalQty,
a.totalAmount,
case when a.ct = sum(b.ct) then 'true' else 'false' end as 'ifNew'
from ( select d.productRowId,
p.name,
DATE_FORMAT(o.effectiveTime, '%m/%Y') as 'dt',
p.rowId,
p.businessLiaision,
p.channel,
count(*) as 'ct',
sum(d.qty) as 'totalQty',
sum(d.amountPostDiscount) as 'totalAmount'
from transactionParty as p
join transactionOrderHist as o on p.rowId = o.transactionPartyRowId
join transactionOrderDetailHist as d on o.rowId = d.orderRowId
where o.businessType = 'sales'
group by d.productRowId, p.name, DATE_FORMAT(o.effectiveTime, '%m/%Y'), p.rowId, p.businessLiaision, p.channel
) as a
left join ( select d.productRowId,
p.name,
DATE_FORMAT(o.effectiveTime, '%m/%Y') as 'dt',
count(*) as 'ct'
from transactionParty as p
join transactionOrderHist as o on p.rowId = o.transactionPartyRowId
join transactionOrderDetailHist as d on o.rowId = d.orderRowId
where o.businessType = 'sales'
group by d.productRowId, p.name, DATE_FORMAT(o.effectiveTime, '%m/%Y')
) as b on b.productRowId = a.productRowId and b.name = a.name and b.dt <= a.dt
group by a.productRowId, a.name, a.rowId, a.dt, a.ct, a.businessLiaision, a.channel, a.ct, a.totalQty, a.totalAmount
) as n
group by n.businessLiaision, n.channel, n.name, n.dt, n.ifNew
Explain plan result
enter image description here
Table descriptions
transactionParty
CREATE TABLE `transactionParty` (
`rowId` varchar(50) NOT NULL,
`name` varchar(100) DEFAULT NULL,
`code` varchar(20) DEFAULT NULL,
`businessLiaision` varchar(20) DEFAULT NULL,
`type` varchar(20) DEFAULT NULL,
`contractualType` varchar(20) DEFAULT NULL,
`paymentMethod` varchar(20) DEFAULT NULL,
`partyGroup` varchar(20) DEFAULT NULL,
`channel` varchar(20) DEFAULT NULL,
`costCenter` varchar(20) DEFAULT NULL,
`warehouseRowId` varchar(100) DEFAULT NULL,
`taxOption` varchar(20) DEFAULT NULL,
PRIMARY KEY (`rowId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
transactionOrderHist
CREATE TABLE `transactionOrderHist` (
`rowId` varchar(50) NOT NULL COMMENT '明道记录ID',
`orderId` varchar(50) DEFAULT NULL COMMENT '单据ID',
`orderCreationTime` datetime DEFAULT NULL COMMENT '单据创建时间',
`orderCreator` varchar(20) DEFAULT NULL COMMENT '单据创建人',
`businessType` varchar(20) DEFAULT NULL COMMENT '业务类型',
`businessLiaision` varchar(20) DEFAULT NULL COMMENT '内部业务负责人,如业务员/采购/文员',
`transactionPartyRowId` varchar(50) DEFAULT NULL COMMENT '往来单位',
`outboundWarehouse` varchar(50) DEFAULT NULL COMMENT '发货仓',
`inboundWarehouse` varchar(50) DEFAULT NULL COMMENT '收货仓',
`outboundWarehouseType` varchar(50) DEFAULT NULL,
`inboundWarehouseType` varchar(50) DEFAULT NULL,
`effectiveTime` datetime DEFAULT '0000-00-00 00:00:00' COMMENT '单据过账时间',
`orderEffectuater` varchar(20) DEFAULT NULL COMMENT '单据过账人',
`remark` varchar(200) DEFAULT NULL,
`productCount` int(10) DEFAULT NULL,
`totalUnitCount` int(10) DEFAULT NULL,
`totalCostAmount` decimal(10,0) DEFAULT NULL,
`totalPostDiscountAmount` decimal(10,0) DEFAULT NULL,
`paymentStatus` varchar(50) DEFAULT NULL,
`paymentDate` datetime DEFAULT NULL,
`outboundWarehouseRowId` varchar(50) DEFAULT NULL,
`inboundWarehouseRowId` varchar(50) DEFAULT NULL,
PRIMARY KEY (`rowId`) USING BTREE,
KEY `orderEffectiveDate` (`effectiveTime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
transactionOrderDetailHist
CREATE TABLE `transactionOrderDetailHist` (
`rowId` varchar(50) NOT NULL,
`orderRowId` varchar(50) DEFAULT NULL,
`productRowId` varchar(50) DEFAULT NULL,
`qty` int(20) DEFAULT NULL,
`price` decimal(20,2) DEFAULT NULL,
`cost` decimal(20,2) DEFAULT NULL,
`amount` decimal(20,2) DEFAULT NULL,
`amountPostDiscount` decimal(20,2) DEFAULT NULL,
`type` varchar(50) DEFAULT NULL,
`effectiveTime` datetime DEFAULT NULL,
`costAmount` decimal(20,2) DEFAULT NULL,
PRIMARY KEY (`rowId`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
FROM ( SELECT ... )
[LEFT] JOIN ( SELECT ... ) ON ...
is notoriously inefficient. Try to rewrite the query to avoid such.
Please provide EXPLAIN SELECT ...; meanwhile, I will do some guessing.
These indexes may help:
d: INDEX(orderRowId, productRowId, qty, amountPostDiscount)
o: INDEX(businessType, transactionPartyRowId, effectiveTime, rowId)
Looking at the final GROUP BY. It does not necessarily order the rows. If you want a particular order, add an ORDER BY. Be aware that the dt part is not quite in chronological order since it has month before year. The other group-bys are in derived tables, so an ORDER BY would be ignored.
If and b.name = a.name and b.dt <= a.dt is for doing "groupwise-max", that is the performance bottleneck. There are much better ways to do it. See Groupwise-Max .
If the text is in Chinese, you should consider converting to utf8mb4 -- utf8 is missing the 4-byte UTF-8 Chinese characters.
It is OK to have the PRIMARY KEY as VARCHAR(50), but it could be better to use INT. Is some outside process providing the rowId?

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;

SELECT DEFAULT returns NULL

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

Mysql select * from a where doesnt exist in b

Im having problems with constructing a query which filters out posts from table a, that already existing in table b.
Table A:
`bok_id` int(6) NOT NULL AUTO_INCREMENT,
`tid` time NOT NULL,
`datum` date NOT NULL,
`datum_end` date NOT NULL,
`framtid` varchar(5) NOT NULL,
`h_adress` varchar(100) NOT NULL,
`l_adress` varchar(100) NOT NULL,
`kund` varchar(100) NOT NULL,
`typ` varchar(5) NOT NULL,
`bil` varchar(99) NOT NULL,
`sign` varchar(2) NOT NULL,
`tilldelad` varchar(12) NOT NULL,
`skapad` datetime NOT NULL,
`endrad` datetime NOT NULL,
`endrad_av` varchar(2) NOT NULL,
`kommentar` text NOT NULL,
`weektype` varchar(3) NOT NULL,
`Monday` tinyint(1) NOT NULL,
`Tuesday` tinyint(1) NOT NULL,
`Wednesday` tinyint(1) NOT NULL,
`Thursday` tinyint(1) NOT NULL,
`Friday` tinyint(1) NOT NULL,
`Saturday` tinyint(1) NOT NULL,
`Sunday` tinyint(1) NOT NULL,
`avbokad` varchar(2) NOT NULL,
`unika_kommentarer` varchar(2) NOT NULL,
UNIQUE KEY `bok_id` (`bok_id`)
Table B:
`id` int(6) NOT NULL AUTO_INCREMENT,
`bok_id` int(6) NOT NULL,
`tid` time NOT NULL,
`datum` date NOT NULL,
`datum_end` date NOT NULL,
`framtid` varchar(5) NOT NULL,
`h_adress` varchar(100) NOT NULL,
`l_adress` varchar(100) NOT NULL,
`kund` varchar(100) NOT NULL,
`typ` varchar(5) NOT NULL,
`bil` varchar(99) NOT NULL,
`sign` varchar(2) NOT NULL,
`tilldelad` varchar(12) NOT NULL,
`skapad` datetime NOT NULL,
`endrad` datetime NOT NULL,
`endrad_av` varchar(2) NOT NULL,
`kommentar` text NOT NULL,
`weektype` varchar(3) NOT NULL,
`Monday` tinyint(1) NOT NULL,
`Tuesday` tinyint(1) NOT NULL,
`Wednesday` tinyint(1) NOT NULL,
`Thursday` tinyint(1) NOT NULL,
`Friday` tinyint(1) NOT NULL,
`Saturday` tinyint(1) NOT NULL,
`Sunday` tinyint(1) NOT NULL,
`avbokad` varchar(2) NOT NULL,
`unika_kommentarer` varchar(2) NOT NULL,
UNIQUE KEY `id` (`id`)
What i want is a query which hides all rows in Table A which exists in table B IF Table B.tilldelad=Requested Date. (f.e 2013-09-30)
Im not sure this makes any sense?
What i want is to filter out period bookings as they have been executed and therefore exists in table b which indicates it has been.
Since its recurring events the same bok_id can exists SEVERAL times in table B, but only ONCE in table A...
SELECT * FROM bokningar
WHERE bokningar.datum <= '2013-09-30'
AND bokningar.datum_end >= '2013-09-30'
AND bokningar.typ >= '2'
AND bokningar.weektype = '1'
AND bokningar.Monday = '1' ## Monday this is dynamically changed to current date
AND bokningar.avbokad < '1'
AND NOT EXISTS ( SELECT 1 FROM tilldelade WHERE tilldelade.tilldelad = '2013-09-30' )
The above code does the trick regarding filtering out rows not in table B, however, if one row in table B has the current date, all results are filtered out.
Only rows with corresponding bok_id's is supposted to get filtered out.
Any thoughts on how to do that? Perhaps a Distinct select?
Typically, NOT IN subselects are quite expensive in querying time. This can normally be handled by doing a LEFT-JOIN and Keeping only those where the other table IS NULL like...
SELECT *
FROM
bokningar
LEFT JOIN tilldelade
on bokningar.bok_id = tilldelade.bok_id
AND tilldelade.tilldelad = '2013-09-30'
WHERE
bokningar.datum <= '2013-09-30'
AND bokningar.datum_end >= '2013-09-30'
AND bokningar.typ >= '2'
AND bokningar.weektype = '1'
AND bokningar.Monday = '1' ## Monday this is dynamically changed to current date
AND bokningar.avbokad < '1'
AND tilldelade.bok_id IS NULL
try something like
SELECT ...
FROM TABLEA
WHERE TABLEA.tilldelad=Requested Date
AND NOT EXISTS (SELECT 1 FROM TABLEB
WHERE TABLEB.tilldelad=Requested Date
AND TABLEA.bok_id = TABLEB.bok_id
AND...)
You need to do set operations.
A simple minus Query would solve your problem here.
Select * from tableA
minus
Select * from tableB;
This would display all data in tableA which is not present in tableB.
You can read more about it over here. http://en.wikipedia.org/wiki/Set_operations_%28SQL%29
For your specific case, try this :
Select * from tableA A
minus
Select * from tableB B where B.tilldelad='3013-09-30';

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