I have a large table:
create table data
(
id bigint unsigned auto_increment primary key,
first varchar(120) null,
last_ varchar(120) null,
country varchar(30) not null
)
collate = utf8mb4_unicode_ci;
I need to display the number of people from individual countries on list.
I a have typical SQL query:
public function getAll(): array
{
$this->db->query('SELECT * FROM data ORDER by id DESC;');
return $this->db->resultSet();
}
but I don't know to how group my results :(
I print my result:
$this->model->getAll()
and then foreach....
In result I need:
1. 10 users from Poland;
2. 101 users from Germany;
3. 99 users from UK....
Please help me
You seem to be looking for simple aggregation:
select country, count(*) no_users from data group by country order by country;
This gives you two columns, with the country and the number of users. You can then generate the proper string output in your application.
Related
I would like to have some statistics and calculate the percentages of which tools have been chosen the most overall in all the registrations of my database
These are my two tables:
$table_registration = $wpdb->prefix . 'registration';
$table_tools = $wpdb->prefix . 'tools';
wp_registration table:
CREATE TABLE $table_registration
(
reg_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
dato date,
billedeURL VARCHAR(80) NOT NULL,
fiske_vaegt DECIMAL( 2,1 ) NOT NULL,
fiske_laengde INT NOT NULL,
reg_user_id BIGINT UNSIGNED NOT NULL,
reg_tools_id INT UNSIGNED NOT NULL
PRIMARY KEY (reg_id),
FOREIGN KEY (reg_user_id) REFERENCES wp_users(id),
FOREIGN KEY (reg_tools_id) REFERENCES $table_tools(tools_id)
)
wp_tools table:
CREATE TABLE $table_tools
(
tools_id INT UNSIGNED AUTO_INCREMENT NOT NULL,
tools_navn CHAR (20),
PRIMARY KEY (tools_id)
)
I have been trying to create the correct mysql but with no luck so this is what I've been doing up till now.
select l.*, concat(round(100 * count(t.reg_tools_id) / t2.cnt,0),'%')
from wp_registration l
left join wp_tools t on l.toolss_id = t.reg_id
cross join
(select count(*) cnt
from wp_registration
where reg_tools_id = 1) t2
group by l.reg_id;
But it tells me that every tool has been used 50% of the times. which obviously is wrong I have three tools users can choose from and right now have 1 - two votes and 2 - nine votes and 3 - two votes there are 13 registrations in total
Hopefully, I understand what do you need !
SELECT
tools.tools_id,
((COUNT(*) / (SELECT COUNT(*) FROM registration)) * 100) AS percent
FROM
registration
JOIN
tools ON registration.reg_tools_id = tools.tools_id
GROUP BY
tools.tools_id
ORDER BY
percent DESC
LIMIT 1
Some remarks :
Try to write in a pure sql
You do not need a php tag for this question
Minimize your code from unnecessary part
Use the concat and round functions in the programming language that you are using not in SQL (I think you are using php here, so do the query then get the result and apply the round and the concat in php instructions)
I had some help with this code:
SELECT *, IF(newcost - cost > 500, newcost - cost, 0) as raiseby FROM
(
SELECT bp.*, b.company,(IF(bp.cost*1.2 < ls.maximumbid, bp.cost*1.2, bp.cost)) as newcost
FROM `windows_brands_products` bp
LEFT JOIN `windows_brands` b
ON bp.brand_id = b.id
JOIN Windows_last_submissions ls
JOIN windows_materials dm
WHERE ls.username = '$current_user->user_login'
AND bp.width = ROUND(ls.width)
AND bp.height = ROUND(ls.height)
AND bp.material IN (dm.name)
AND bp.type = ls.type
AND IF (ls.minimumbid != '0.00',bp.cost BETWEEN ls.minimumbid AND ls.maximumbid,bp.cost <= ls.maximumbid)
ORDER BY b.company ASC
) as temptable
The goal is to display a line stating that the user missed a (or some) companies by $500 and state how much the user needs to increase their max. bid (ls.maximum) in order to come within parameters of the query. It looks to me like it will look something like:
echo 'If you increase your maximum bid by '.$row->raiseby.',. $row->temptable.'can perform your installation';
I don't seem to get a positive response by using that statement...My assumptions could also be off about the way to reference each "row".
Am I wrong to assume that when you use "AS" parameter in sql the word to the right becomes the new row name?
Anyone have any idea as to how I could word this query to achieve my results?
Thanks
EDIT* I'm having a problem with sqlfiddle showing an error I can't figure out. it states 'incorrect integer value: column 'id' row 1':
CREATE TABLE windows_brands
(
id int(11),
company varchar(255)
);
INSERT INTO windows_brands
VALUES ('1','Anderson');
CREATE TABLE windows_brands_products
(
id int(11) AUTO_INCREMENT,
brand_id int(11),
width decimal(12,2),
height decimal(12,2),
material varchar(30),
type varchar(30),
cost decimal(12,2),
PRIMARY KEY (id)
);
INSERT INTO windows_brands_products
VALUES ('','2','30','36','wood','double hung','1500.00');
CREATE TABLE Windows_submissions
(
id int(11) AUTO_INCREMENT,
name varchar(30),
username varchar(12),
width decimal(12,2),
height decimal(12,2),
chosenmaterial varchar(30),
type varchar(30),
minimumbid decimal(12,2),
maximumbid decimal(12,2),
PRIMARY KEY (id)
);
INSERT INTO Windows_submissions
VALUES ('','Casey','caseys','30','36','wood','double hung','1000.00','1700.00');
CREATE TABLE windows_materials
(
id int(11) AUTO_INCREMENT,
name varchar(30),
PRIMARY KEY (id)
);
INSERT INTO windows_materials
VALUES ('','wood');
Can you see what the problem is - I've been looking it over for a while and can't see it.
This query works fine: http://sqlfiddle.com/#!9/22a74/1
In the query I'm trying to get to work...If, say, I make a maximumbid of $300 (for example) more than what the company charges, I should be able to echo something in a loop like, the nearest company is ____ and is $300 more than your maximumbid. I just don't know how to reference the aliases like 'raiseby' and 'temptable'. If I put that query into sqlfiddle 0 results show...which I want the same results like the company and the newcost to show- but also I want to let the user know how much they missed the target if, say, no results show.
I have a table that contains millions of sales records and looks like this:
CREATE TABLE `sales` (
`dollar_amount` INT NULL,
`transaction_date` DATE NULL,
`company_name` VARCHAR(45) NULL,
`company_id` INT NULL);
The first three columns are populated with data. I would like to insert data into the company_id column that will identify each company with an auto_incremented integer. I plan to use the company_id field as a foreign key referencing another table that will contain each company's details. Many companies have multiple transactions, so the code needs to assign the same company_id to each row in the sales table with a matching company_name.
Is there a way to do this using only MySQL?
First, I'd recommend creating the company table:
CREATE TABLE company (
company_id INT NOT NULL AUTO_INCREMENT,
company_name VARCHAR(45),
PRIMARY KEY(company_id));
Then insert the companies from your sales data:
INSERT INTO company (company_name)
SELECT distinct company_name
FROM sales;
Finally, update your sales table with a join to get the company_id:
UPDATE sales s
JOIN company c ON s.company_name = c.company_name
SET s.company_id = c.company_id;
SQL Fiddle Demo
You should also remove the company_name field from the sales table since this is now stored in the company table.
To define an auto incremented integer, you just use the AUTO_INCREMENT keyword. However, if you define any columns as auto_increment, you must also make that column your primary key. Which, in this case, would make sense in order for it to be a foreign key elsewhere.
Try this:
CREATE TABLE `sales` (
`dollar_amount` INT NULL,
`transaction_date` DATE NULL,
`company_name` VARCHAR(45) NULL,
`company_id` INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(company_id);
SQL Fiddle
I created this query to display my auto complete box with jQuery. It is working perfectly.
<?php
require_once('database.php');
if(isset($_POST['queryString'])) {
$queryString = $dbc->real_escape_string($_POST['queryString']);
if(strlen($queryString) >0) {
$q = "SELECT keyword
FROM (
SELECT tname AS keyword FROM t
UNION
SELECT sname AS keyword FROM sub
UNION
SELECT cname AS keyword FROM c
UNION
SELECT iname AS keyword FROM i
) s
WHERE keyword LIKE '%$queryString%'
LIMIT 10";
$r = mysqli_query ( $dbc, $q);
if($q) {
while ($row = mysqli_fetch_array($r, MYSQL_ASSOC)) {
echo '<li onClick="fill(\''.$row['keyword'].'\');">'.$row['keyword'].'</li>';
}
} else {
echo 'ERROR: There was a problem with the query.';
}
} else {
}
} else {
echo 'There should be no direct access to this script!';
}
?>
with this query display auto complete list with subjects, tutor names, cities according the keyword. Now I need to modify auto complete list with more values. For an example there is a tutor name in the list I want to display his/her current city, his/her profile image etc. It is something similar to Facebook search.
this is my city and address tables
# --------------
# Address Table
# --------------
CREATE TABLE address (
address_id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT,
address_one VARCHAR(40) NOT NULL,
address_two VARCHAR(40) DEFAULT NULL,
city_id INT(4) UNSIGNED NOT NULL,
PRIMARY KEY (address_id),
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
# --------------
# City Table
# --------------
CREATE TABLE city(
city_id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT,
city_name VARCHAR(30) NOT NULL,
district_id INT(2) UNSIGNED NOT NULL,
PRIMARY KEY (city_id),
UNIQUE (city_name)
) ENGINE=MyISAM;
How can I do this?
I think there are 2 options.
I believe you should adjust your query, because now you look in the t table and in the sub table checking if the searchword occurs. However, your query is so short that you dont have available the matching profile info, just the column on which you perform the search.
Ofcourse you dont want to query a lot of data from rows that dont even match your criteria. On the other hand, its not so convenient to do a lot of queryies after you performed the search. However, since you have limit to 10, it should be okay.
Change your query to select name, birthday, gender, imgdata from t etc..
I have created this database schema and with help from several users on here, I have a database which takes user submitted business entries stored in the business table, which are additionally grouped under one or several of about 10 catagories from the catagories table, in the tbl_works_catagories table by matching the bus_id to the catagory id.
For example, bus_id 21 could be associated with catagory_id 1, 2, 5, 7, 8.
CREATE TABLE `business` (
`bus_id` INT NOT NULL AUTO_INCREMENT,
`bus_name` VARCHAR(50) NOT NULL,
`bus_dscpn` TEXT NOT NULL,
`bus_url` VARCHAR(255) NOT NULL,
PRIMARY KEY (`bus_id`)
)
CREATE TABLE `categories` (
`category_id` INT NOT NULL AUTO_INCREMENT,
`category_name` VARCHAR(20) NOT NULL,
PRIMARY KEY (`category_id`)
)
CREATE TABLE `tbl_works_categories` (
`bus_id` INT NOT NULL,
`category_id` INT NOT NULL
)
Now, what i want to do next is a search function which will return businesses based on the catagory. For example, say one of the businesses entered into the business table is a bakers and when it was entered, it was catagorised under Food (catagory_id 1) and take-away (catagory_id 2).
So a visitor searches for businesses listed under the Food catagory, and is returned our friendly neighbourhood baker.
As with all PHP/MySQL, i just can't (initially anyway) get my head around the logic, never mind the code!
You should setup foreign keys in your tables to link them together.
CREATE TABLE `business` (
`bus_id` INT NOT NULL AUTO_INCREMENT,
`bus_name` VARCHAR(50) NOT NULL,
`bus_dscpn` TEXT NOT NULL,
`bus_url` VARCHAR(255) NOT NULL,
PRIMARY KEY (`bus_id`)
)
CREATE TABLE `categories` (
`category_id` INT NOT NULL AUTO_INCREMENT,
`category_name` VARCHAR(20) NOT NULL,
PRIMARY KEY (`category_id`)
)
CREATE TABLE `tbl_works_categories` (
`bus_id` INT NOT NULL,
`category_id` INT NOT NULL,
FOREIGN KEY (`bus_id`) REFERENCES business(`bus_id`),
FOREIGN KEY (`category_id`) REFERENCES categories(`category_id`)
)
Then your search query would be something like:
SELECT b.*
FROM business b, categories c, tbl_works_categories t
WHERE
b.bus_id = t.bus_id AND
c.category_id = t.category_id AND
c.category_id = *SOME SEARCH VALUE*
which using JOIN would be written as:
SELECT b.*
FROM business b
JOIN tbl_works_categories t
ON b.bus_id = t.bus_id
JOIN categories c
ON c.category_id = t.category_id
WHERE c.category_id = *SOME SEARCH VALUE*
Maybe you want something like this:
SELECT `bus_id` FROM `tbl_works_categories` WHERE `category_id` = *some id from the search*
AND `category_id` = *some other id from the search*;
Although you'd need those ids- there are a few ways to do this, I'll describe probably the most straight forward...
You get categories from $_POST, so let's just say you have 2 of them entered. (Food, and take-away). Parse these however you want, there are multiple ways, but the point is they're coming from $_POST.
execute this sort of thing for each one you find:
SELECT `category_id` FROM `categories` WHERE `category_name` LIKE '%*the name from $_POST*%';
Store these results in an array...based on how many you have there you can build an applicable query similar to the one I describe first. (Keep in mind you don't need and AND there, that's something you have to detect if you return > 1 category_id from the second query here)
I'm not going over things like security..always be careful when executing queries that contain user submitted data.
An alternate solution might involve a join, not too sure what that'd look like off the top of my head.
Good luck.
If you want all businesses that are related to the given category-id, your SQL-statement would look something like this:
SELECT `business`.`bus_name`
FROM `business`
WHERE `business`.`bus_id` = `tbl_works_categories`.`bus_id`
AND `categories`.`category_id` = `tbl_works_categories`.`category_id`
AND `categories`.`category_id` = 1;
Where 1 in this case is your food-category, but could be your PHP variable where the ID of the category the user selected is stored.
And one hint: Be sure to name your tables either in plurar or in singular. You are mixing both and could get confused.