SQL - Get Count - java

I have a table called COMPANIES that contains info on different companies. How do make a query that gets the company state(COMPANY_STATE) and the company name(COMPANY) count of the most used state (COMPANY_STATE) which has the highest number of different COMPANIES in it. So say Ohio has the most companies in it with 50. How to I query the database to get the state
| COMPANY_STATE | COUNT |
+---------------+-------+
| OH | 50 |
+---------------+-------+
Can i do this via query or do i have to have my java program actually do the work?
Table.sql
CREATE TABLE COMPANIES (
ID INT NOT NULL AUTO_INCREMENT,
COMPANY varchar(255) NOT NULL,
COMPANY_CODE char(10) NOT NULL,
COMPANY_ADDRESS varchar(255),
COMPANY_STATE char(2) NOT NULL,
COMPANY_WORKFORCE INT,
PRIMARY KEY (ID)
)

SELECT COMPANY_STATE, COUNT(ID) FROM COMPANIES
GROUP BY COMPANY_STATE
ORDER BY COUNT(ID) DESC
LIMIT 1

Related

Unique constraints & insert or update for both MySQL and SQLite

I am looking for a way to define a set of columns as unique and then insert a new entry into the table or update the row if the columns aren't unique. I have done some research and found ways to do it, but I couldn't find anything that is compatible with both MySQL and SQLite.
Say I have the following table:
CREATE TABLE `users` (
`id` INT NOT NULL AUTO_INCREMENT,
`uuid` VARCHAR ( 64 ) NOT NULL,
`name` VARCHAR ( 32 ) NOT NULL,
`date` BIGINT NULL,
PRIMARY KEY ( id )
);
I want uuid and date to be unique so that there can be multiple entries for one uuid or one date, but not for one combination of uuid and date. What I initially wanted to do is set the primary key to those:
PRIMARY KEY ( uuid, date )
However, for some reason I won't be able to use null values for date when doing this.
I have also found something about a constraint, but I am not sure if this works:
CONSTRAINT user UNIQUE ( `uuid`, `date` )
Now I want to insert a new row into this table, but update the existing row if a row with the same uuid and date already exists. I have found a few ways but they are either not doing what I want or not compatible with both MySQL and SQLite:
INSERT INTO ... ON DUPLICATE KEY doesn't work with SQLite
REPLACE INTO will delete anything I don't specify instead of updating
I have been doing research for quite a while but I couldn't find a solution that worked for me. Any help appreciated.
SQLite solution (same principle should apply in mysql)
You could simply add a UNIQUE index (at least for SQLite for which this is for) so you could have :-
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` INTEGER, //<<<<<<<<<< See notes below
`uuid` VARCHAR ( 64 ) NOT NULL,
`name` VARCHAR ( 32 ) NOT NULL,
`date` BIGINT NULL,
PRIMARY KEY ( `id` )
);
CREATE UNIQUE INDEX IF NOT EXISTS uuid_date ON `users` (`uuid`,`date`); //<<<<<<<<<<
Note AUTO_INCREMENT results in a failure for SQLite as it's not a keyword, the correct keyword in SQlite is AUTOINCREMENT. However, it's been omitted as it's probably not required as INTEGER PRIMARY KEY (or the implicit by specifiying PRIMARY KEY (id)) will result in a uniqiue id being automatically generated if no value is supplied for the column when inserting.
SQLite requires INTEGER, not INT, for the automatically generated id. NOT NULL and also UNIQUE are implied so no need to specify them.
Here's two sets of example inserts each duplicating the uuid/date combination thus updating instead of inserting and also inserting with same uuid but different date and vice-versa :-
INSERT OR REPLACE INTO `users` VALUES(null,'Fred01234567','Fred Bloggs the 1st','20180101');
INSERT OR REPLACE INTO `users` VALUES(null,'Fred01234567','Fred Bloggs the 2nd','20180101'); -- <<<< DUPLICATE
INSERT OR REPLACE INTO `users` VALUES(null,'Fred99999999','Fred Bloggs the 2nd','20180101'); -- <<<< different uuid same date
INSERT OR REPLACE INTO `users` VALUES(null,'Fred01234567','Fred Bloggs the 2nd','99999999'); -- <<<< same uuid different date
INSERT OR REPLACE INTO `users` (`uuid`,'name','date') VALUES('Fred76543210','Fred NotBloggs the 1st','20180202');
INSERT OR REPLACE INTO `users` (`uuid`,'name','date') VALUES('Fred76543210','Fred NotBloggs the 1st','20180202');
INSERT OR REPLACE INTO `users` (`uuid`,'name','date') VALUES('Fred99999999','Fred NotBloggs the 1st','20180202');
INSERT OR REPLACE INTO `users` (`uuid`,'name','date') VALUES('Fred76543210','Fred NotBloggs the 1st','99999999');
SELECT * FROM `users`;
Results are :-
I have been googling for a few hours and did some testing with both MySQL and SQLite and I think I found a working solution.
To make the combination of uuid and date unique, I have added a unique constraint to the table. To insert a new row or 'update' an existing row, I am using REPLACE INTO ... SELECT.
To create the table:
CREATE TABLE IF NOT EXISTS `users` (
`id` INT NOT NULL AUTO_INCREMENT, // use INTEGER NOT NULL for SQLite
`uuid` VARCHAR ( 64 ) NOT NULL,
`name` VARCHAR ( 32 ) NOT NULL,
`date` BIGINT NULL,
CONSTRAINT `uuid_date` UNIQUE ( `uuid`, `date` ),
PRIMARY KEY ( `id` )
);
The CONSTRAINT will make sure the combination of uuid and date is always unique.
For inserting data, I use REPLACE INTO ... SELECT, where I enter all (new) values in the SELECT query and enter the column names for all columns I haven't specified a value for, to ensure it will keep their values intact rather than deleting them when the existing row is replaced.
REPLACE INTO `users`
SELECT `id`, `uuid`, ?, `date`
FROM `users` WHERE `uuid` = ? AND `date` = ?;
Of course, because in this case there are no columns that can be lost when using a normal REPLACE INTO, so I could also use:
REPLACE INTO `users` ( `uuid`, `name`, `date` ) VALUES ( ?, ?, ? );
However, the REPLACE INTO ... SELECT query can be useful when I have a table with more columns and there are actually columns that can be lost when not selecting them.
Sorry about all the comments. Here is how I achieved what I think you are going for. You are going to lose the id as Primary Key on your users table. You will also have to stage your insert variables in a table. But you will get your end results. Sorry I do not have a better solution.
DROP TABLE users;
DROP TABLE users2;
CREATE TABLE `users` (
`uuid` VARCHAR ( 64 ) NOT NULL,
`name` VARCHAR ( 32 ) NOT NULL,
`date` BIGINT NULL
);
ALTER TABLE `users` ADD PRIMARY KEY(`uuid`,`date`);
INSERT INTO users (`name`,`uuid`,`date`) SELECT '','123','2018-04-01';
CREATE TABLE `users2` (
`uuid` VARCHAR ( 64 ) NOT NULL,
`name` VARCHAR ( 32 ) NOT NULL,
`date` BIGINT NULL
);
INSERT INTO users2 (`name`,`uuid`,`date`) SELECT 'brad','123','2018-04-01';
REPLACE INTO users SELECT `uuid`,`name`,`date` FROM users2 GROUP BY `uuid`,`date`;
SELECT * FROM users;`

MYSQL update with inner join performance

The join is done on the primary key column of both these tables.
I have a doubt if I should fire a select query before the update or will this query be a good alternative?(in terms of performance)
order item table
order_item_id
order_id
quantity
unit_price
shipping_price
business_id
workflow_id
delivery_id
item_id
Orders table
billing_address_id
shipping_address_id
payment_mode
total_price
shipping_price
customer_id
order_id
Following is the query I fire from my Java service (using jdbc) :
UPDATE order_items t1
INNER
JOIN Orders t2
ON t2.order_id = t1.order_id
SET t1.workflow_id = ?
WHERE t1.order_item_id = ?
and t2.order_id = ?
and t2.customer_id = ?
and t1.delivery_id = ?
UPDATE : Adding show create table order_items
'CREATE TABLE `order_items` (
`order_item_id` int(20) NOT NULL AUTO_INCREMENT,
`quantity` int(10) unsigned NOT NULL,
`unit_price` int(10) unsigned NOT NULL,
`shipping_price` int(10) unsigned NOT NULL,
`pickup_date` datetime DEFAULT NULL,
`create_TS` datetime DEFAULT CURRENT_TIMESTAMP,
`update_TS` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`business_id` int(10) NOT NULL,
`order_id` int(11) NOT NULL,
`item_id` int(10) unsigned NOT NULL,
`delivery_id` int(11) NOT NULL,
`workflow_id` int(11) DEFAULT NULL,
PRIMARY KEY (`order_item_id`),
KEY `fk_business_id` (`business_id`),
KEY `fk_order_id` (`order_id`),
KEY `fk_item_id` (`item_id`),
KEY `fk_delivery_id` (`delivery_id`),
CONSTRAINT `fk_business_id` FOREIGN KEY (`business_id`) REFERENCES `business` (`MID`),
CONSTRAINT `fk_delivery_id` FOREIGN KEY (`delivery_id`) REFERENCES `delivery_mode` (`delivery_id`),
CONSTRAINT `fk_item_id` FOREIGN KEY (`item_id`) REFERENCES `item_business` (`item_id`),
CONSTRAINT `fk_order_id` FOREIGN KEY (`order_id`) REFERENCES `Orders` (`order_id`)
)
Talking in theory
You should have the minimum set of data before you do the join, so the join will actually be performed only on the data you need, and that is the case even with the update that is internally a special select and "write this data on the select"
Talking in practice
One of the job of any dbms is to perform an agressive level of optimization using database algebra and other stuff, so most of the time the time you spend in optimizing your query is actually futile because your dbms will perform the same level of optimization
So what
I would try to have the table the slimmest as possible but without getting too crazy, I performed on a aws db2.micro machine an update query on like 100k rows and it took it like 4 seconds, so in my opinion, try and see if you're getting the real result you need.
tl;dr just try and see if the speed increase

Count Number of Users in Cassandra column family?

I have a table like this in Cassandra-
CREATE TABLE DATA_HOLDER (USER_ID TEXT, RECORD_NAME TEXT, RECORD_VALUE BLOB, PRIMARY KEY (USER_ID, RECORD_NAME));
I want to count distinct USER_ID in my above table? Is there any way I can do that?
My Cassandra version is:
[cqlsh 4.1.1 | Cassandra 2.0.10.71 | DSE 4.5.2 | CQL spec 3.1.1 | Thrift protocol 19.39.0]
The select expression is defined as:
selection_list
| DISTINCT selection_list
so you can:
SELECT DISTINCT USER_ID FROM DATA_HOLDER;

query with INNER JOIN

The tables are created and have some data inserted I am trying to get the route from the arrivaltimes table with the aid of JOIN INNER but I am getting nothing back I have already tried to adjust the time to the current time tin th arrivaltimes table but the result is always empty. I am not getting any error. Is something wrong with my query?
CREATE TABLE IF NOT EXISTS stops
(stop_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(30) NOT NULL,
lat double(10,6) NOT NULL,
longi double(10,6)NOT NULL)
CREATE TABLE IF NOT EXISTS arrivaltimes
(arrivaltimes_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
weekday VARCHAR(20) NOT NULL,
route INT(11) NOT NULL,
arrivaltime time NOT NULL,
stop_id INT, FOREIGN KEY fk_stop_id(stop_id) REFERENCES stops(stop_id) )
SELECT route from arrivaltimes INNER JOIN stops ON arrivaltimes.stop_id=stops.stop_id where arrivaltime = now()
arrivaltime is having datatype time and its in the format H:i:s.
In the where clause you are using now() and it will be in the format Y-m-d H:i:s
You need to use curtime function for that.
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2015-05-10 23:46:44 |
+---------------------+
1 row in set (0.00 sec)
mysql> select curtime();
+-----------+
| curtime() |
+-----------+
| 23:46:53 |
+-----------+
1 row in set (0.00 sec)
where arrivaltime = curtime()
your query is perfectly fine the problem is only with the time you provide as input.
The format of TIME data type is 'HH:MM:SS' so use time(now()) this will give you proper results.
mysql> select time(now());

Nullable Foreign Key Constraints

We are trying increase the scope of database compatibility for our web application. Our application is Java EE with JSPs, Servlets, and EJBs. The database we are trying to make our application compatible with is SQL Server 2008.
The problem we are running into is that our application uses nullable foreign keys in many cases in many files. These nullable foreign keys work in other databases but we have not found a way to get them to work in SQL Server 2008 because it will only allow a single foreign key to be 'null' at a given time. We understand that, in general, it is best to avoid such nullable foreign keys. However, this web application is large and it would be quite difficult to change files one-by-one.
Thus far, we have tried the following:
[1] initializing dummy elements in referenced tables so that the foreign keys will point to something.
[2] using 'EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"' in order to remove the foreign key constraint
Unfortunately, initializing dummy elements in [1] above broke many components in the web application.
Unfortunately, trying to remove the constraint according to the statement in [2] above did not work. We suspect this because subsequent attempts to drop each table result in Foreign Key constraint errors.
Currently, clear answers to the following questions would help us make some progress:
[1] Is there a quick fix to allow SQL Server 2008 to allow for multiple 'null'-valued foreign keys?
[2] Is there another workaround we could try that would not involve extensive changes to our web application?
I'm not sure what you are talking about! Possibly if you posted a sample schema, I could understand what you mean.
You can have multiple null FK columns in a table:
build the tables and FKs:
CREATE TABLE dbo.AAAA
(
A_ID int NOT NULL identity(1,1) primary key,
B_ID int NULL,
C_ID int NULL
) ON [PRIMARY]
CREATE TABLE dbo.BBBB
(
B_ID int NOT NULL identity(1,1) primary key,
A_ID int NULL,
C_ID int NULL
) ON [PRIMARY]
CREATE TABLE dbo.CCCC
(
C_ID int NOT NULL identity(1,1) primary key,
A_ID int NULL,
B_ID int NULL
) ON [PRIMARY]
ALTER TABLE dbo.CCCC ADD CONSTRAINT FK_CCCC_AAAA FOREIGN KEY ( A_ID ) REFERENCES dbo.AAAA ( A_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
ALTER TABLE dbo.BBBB ADD CONSTRAINT FK_BBBB_AAAA FOREIGN KEY ( A_ID ) REFERENCES dbo.AAAA ( A_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
ALTER TABLE dbo.CCCC ADD CONSTRAINT FK_CCCC_BBBB FOREIGN KEY ( B_ID ) REFERENCES dbo.BBBB ( B_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
ALTER TABLE dbo.AAAA ADD CONSTRAINT FK_AAAA_BBBB FOREIGN KEY ( B_ID ) REFERENCES dbo.BBBB ( B_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
ALTER TABLE dbo.AAAA ADD CONSTRAINT FK_AAAA_CCCC FOREIGN KEY ( C_ID ) REFERENCES dbo.CCCC ( C_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
ALTER TABLE dbo.BBBB ADD CONSTRAINT FK_BBBB_CCCC FOREIGN KEY ( C_ID ) REFERENCES dbo.CCCC ( C_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
insert sample data:
INSERT INTO AAAA VALUES (NULL,NULL)
INSERT INTO AAAA VALUES (NULL,NULL)
INSERT INTO AAAA VALUES (NULL,NULL)
INSERT INTO BBBB VALUES (1,NULL)
INSERT INTO BBBB VALUES (2,NULL)
INSERT INTO BBBB VALUES (NULL,NULL)
INSERT INTO BBBB VALUES (NULL,NULL)
INSERT INTO BBBB VALUES (1,NULL)
Show the data (see how many FK columns are null):
select * from AAAA
select * from BBBB
select * from CCCC
OUTPUT:
A_ID B_ID C_ID
----------- ----------- -----------
1 NULL NULL
2 NULL NULL
3 NULL NULL
(3 row(s) affected)
B_ID A_ID C_ID
----------- ----------- -----------
1 1 NULL
2 2 NULL
3 NULL NULL
4 NULL NULL
5 1 NULL
(5 row(s) affected)
C_ID A_ID B_ID
----------- ----------- -----------
(0 row(s) affected)
If this isn't what you are talking about, you need to provide some sample tables and data.
remove these test tables:
ALTER TABLE dbo.CCCC drop CONSTRAINT FK_CCCC_AAAA
ALTER TABLE dbo.BBBB drop CONSTRAINT FK_BBBB_AAAA
ALTER TABLE dbo.CCCC drop CONSTRAINT FK_CCCC_BBBB
ALTER TABLE dbo.AAAA drop CONSTRAINT FK_AAAA_BBBB
ALTER TABLE dbo.AAAA drop CONSTRAINT FK_AAAA_CCCC
ALTER TABLE dbo.BBBB drop CONSTRAINT FK_BBBB_CCCC
drop table AAAA
drop table BBBB
drop table CCCC

Categories