0

As requested by @Adyson, I've added my database sample below.

CREATE TABLE test.patients ( id BIGINT NOT NULL AUTO_INCREMENT , branchID INT NOT NULL , patientNo VARCHAR(20) NOT NULL , billingAccounts VARCHAR(50) NOT NULL , firstName VARCHAR(20) NOT NULL , lastName VARCHAR(20) NOT NULL , PRIMARY KEY (id)) ENGINE = InnoDB;

INSERT INTO `patients` (`id`, `branchID`, `patientNo`, `billingAccounts`, `firstName`, `lastName`) VALUES (NULL, '1', 'PN017830', '[\"-1\",\"-2\",\"7632\",\"7774\"]', 'John', 'Daka'), (NULL, '1', 'PN017890', '[\"-1\",\"-2\",\"8120\",\"7742\"]', 'Ann', 'Mikail')


CREATE TABLE `test`.`products` ( `id` INT NOT NULL AUTO_INCREMENT , `type` ENUM('pharmaceutical','other') NOT NULL , `productCode` VARCHAR(50) NOT NULL , `brand` VARCHAR(50) NOT NULL , `manufacturer` INT NOT NULL , `generics` TEXT NOT NULL , `privateBranchID` INT NOT NULL , `regID` INT NOT NULL , `regDate` DATETIME NOT NULL , `status` ENUM('active','deactivated') NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;

INSERT INTO `products` (`id`, `type`, `productCode`, `brand`, `manufacturer`, `generics`, `privateBranchID`, `regBy`, `regDate`, `status`) VALUES (10, 'pharmaceutical', '500015806877', 'gaviscon', '217', '[\"magaldrate\",\"simethicone\"]', '0', '1', CURRENT_TIMESTAMP, 'active'), (11, 'pharmaceutical', '7640153080325', 'lofral', '199', '[\"amlodipine\"]', '0', '1', CURRENT_TIMESTAMP, 'active')

CREATE TABLE `test`.productdiscounts ( `id` BIGINT NOT NULL AUTO_INCREMENT , `branchID` INT NOT NULL , `productID` BIGINT NOT NULL , `accountID` BIGINT NOT NULL , `discount` DECIMAL NOT NULL , `isActive` ENUM('1','0') NOT NULL , `regBy` INT NOT NULL , `regTimestamp` DATETIME on update CURRENT_TIMESTAMP NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;

INSERT INTO `productdiscounts` (`branchID`, `productID`, `accountID`, `discount`, `isActive`, `regBy`, `regTimestamp`) VALUES ('1', '10', '7723', '90', '1', '1', '2022-08-25 08:01:59'), ('1', '10', '7724', '70', '1', '1', '2022-08-25 08:01:59'), ('1', '10', '-2', '70', '1', '1', '2022-08-25 08:01:59'), ('1', '10', '7720', '55', '1', '1', '2022-08-25 08:01:59')

CREATE TABLE chms.patients ( id BIGINT NOT NULL AUTO_INCREMENT , branchID INT NOT NULL , patientNo VARCHAR(20) NOT NULL , billingAccounts VARCHAR(50) NOT NULL , firstName VARCHAR(20) NOT NULL , lastName VARCHAR(20) NOT NULL , PRIMARY KEY (id)) ENGINE = InnoDB;

INSERT INTO patients (id, branchID, patientNo, billingAccounts, firstName, lastName) VALUES (NULL, '1', 'PN017830', '["-1","-2","7632","7774"]', 'John', 'Daka'), (NULL, '1', 'PN017890', '["-1","-2","8120","7742"]', 'Ann', 'Mikail')

CREATE TABLE test.products ( id INT NOT NULL AUTO_INCREMENT , type ENUM('pharmaceutical','other') NOT NULL , productCode VARCHAR(50) NOT NULL , brand VARCHAR(50) NOT NULL , manufacturer INT NOT NULL , generics TEXT NOT NULL , privateBranchID INT NOT NULL , regID INT NOT NULL , regDate DATETIME NOT NULL , status ENUM('active','deactivated') NOT NULL , PRIMARY KEY (id)) ENGINE = InnoDB;

INSERT INTO products (id, type, productCode, brand, manufacturer, generics, privateBranchID, regBy, regDate, status) VALUES (10, 'pharmaceutical', '500015806877', 'gaviscon', '217', '["magaldrate","simethicone"]', '0', '1', CURRENT_TIMESTAMP, 'active'), (11, 'pharmaceutical', '7640153080325', 'lofral', '199', '["amlodipine"]', '0', '1', CURRENT_TIMESTAMP, 'active')

CREATE TABLE test.productdiscounts ( id BIGINT NOT NULL AUTO_INCREMENT , branchID INT NOT NULL , productID BIGINT NOT NULL , accountID BIGINT NOT NULL , discount DECIMAL NOT NULL , isActive ENUM('1','0') NOT NULL , regBy INT NOT NULL , regTimestamp DATETIME on update CURRENT_TIMESTAMP NOT NULL , PRIMARY KEY (id)) ENGINE = InnoDB;

INSERT INTO productdiscounts (branchID, productID, accountID, discount, isActive, regBy, regTimestamp) VALUES ('1', '10', '7723', '90', '1', '1', '2022-08-25 08:01:59'), ('1', '10', '7724', '70', '1', '1', '2022-08-25 08:01:59'), ('1', '10', '-2', '70', '1', '1', '2022-08-25 08:01:59'), ('1', '10', '7720', '55', '1', '1', '2022-08-25 08:01:59')

This is my PHP code:

$searchSQL="
    select 
        distinct 
        products.id,
        products.type as productType,
        products.brand,
        products.status,
        products.productCode,
        products.generics,
        coalesce((select discount from productdiscounts where(productID=products.id and branchID=1 and isActive='1' and patients.billingAccounts like concat('%\"',productdiscounts.accountID,'\"%')) order by discount desc limit 1),0.00) as discount,
        concat('[',(select group_concat('{\"productID\":\"',productdiscounts.productID,'\",\"accountID\":\"',productdiscounts.accountID,'\",\"discount\":\"',productdiscounts.discount,'\",\"accountName\":\"',accounts.name,'\",\"accountNo\":\"',accounts.accountNo,'\"}') from productdiscounts 
        left join accounts on(productdiscounts.accountID=accounts.id)
        where(productdiscounts.productID=products.id and productdiscounts.branchID = 1 and productdiscounts.isActive = '1' )),']') as allDiscounts
    from products 
    left join stock on (products.id=stock.productID) 
    left join pricetags on (stock.priceTag=pricetags.id) 
    left join countries on (products.manufacturer=countries.id)
    left join diagnosis on (diagnosis.diagnosisRef='')
    left join patients on (patients.id=10)
    where(
        products.productCode='' or 
        products.generics like concat('%\"','magaldrate','%\"%') or  
        products.brand like concat('% ','gaviscon','%')
        and (stock.isActive='1' and products.status='active')
        )
    order by products.brand limit 30
";
$productsQ=(new DB)->getRef()->prepare($searchSQL); 
$productsQ->execute([]]);
$productsD=$productsQ->fetchAll();

I have a column (billingAccounts) that stores data as JSON Array like this: ["-1","-2","7632","7774"] and in the product-discount table, I have rows for each company's discount and to get the discount, I use the below code but is a bit slow: [enter image description here][1] select products.brand, coalesce((select discount from productdiscounts where(productID=products.id and branchID=? and isActive='1' and patients.billingAccounts like concat('%"',productdiscounts.accountID,'"%')) order by discount desc limit 1),0.00) as discount from products left join patients on (patients.patientNo=diagnosis.patientNo) .....

ALL I WANT IS TO RETURN THE MAXIMUM DISCOUNT FROM THE company ACCOUNTS THAT HAVE DISCOUNT ON THE PRODUCT AND ALSO MATCHES IN THE PATIENT BILLING ACCOUNS.

Note: I don't want to use concat or group_concat because is what I'm currently using and it's making the query to be slow!

NAL
  • 3
  • 2
  • 1
    I suggest normalising your data structure instead of taking shortcuts with JSON strings. This is not an identical scenario, but it's very closely related: [Is storing a delimited list in a database column really that bad?](https://stackoverflow.com/questions/3653462/is-storing-a-delimited-list-in-a-database-column-really-that-bad) – ADyson Aug 24 '22 at 14:10
  • I did that and to get the discount I had to use concat with like which makes the query to be slow and that's why i decided to pack all in a json column and still couldn't get it which makes me ask this question. – NAL Aug 24 '22 at 22:31
  • If you had to use concat to do anything other than just put two values together for presentational purposes then it almost certainly wasn't fully/correctly normalised. Either that or you've misunderstood something. Provide some sample data (as text not pictures, from the non-JSON, supposedly normalised version of your database), expected output of your query and an adequate explanation of the logic you're trying to implement and we might be able to make some progress towards a solution – ADyson Aug 24 '22 at 22:55
  • @ADyson I've added the database query. Thank you – NAL Aug 25 '22 at 15:12
  • Thanks. However it's very difficult to read all that, the way it's presented. Have a look at [How do I format my posts?](https://stackoverflow.com/help/formatting) please, and try again to format the code in a readable way. Thanks. – ADyson Aug 25 '22 at 15:19

0 Answers0