How can I display the frequency of the number of students in a class. I have several tables in the database.
table = kelas
+----+---------+---------+
| id | tingkat | nama |
+----+---------+---------+
| 1 | 5 | Kelas 5 |
| 2 | 3 | Kelas 3 |
+----+---------+---------+
table = siswa
+----+----------+
| id | nama |
+----+----------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
etc.
table = kelas_siswa
+----+----------+----------+------+
| id | id_kelas | id_siswa | ta |
+----+----------+----------+------+
| 18 | 1 | 18 | 2019 |
| 19 | 1 | 19 | 2019 |
| 20 | 1 | 20 | 2019 |
| 21 | 1 | 21 | 2019 |
| 22 | 1 | 22 | 2019 |
| 23 | 1 | 23 | 2019 |
| 24 | 1 | 24 | 2019 |
| 25 | 1 | 25 | 2019 |
| 26 | 1 | 26 | 2019 |
| 27 | 1 | 27 | 2019 |
| 28 | 1 | 28 | 2019 |
| 29 | 1 | 29 | 2019 |
| 30 | 1 | 30 | 2019 |
| 31 | 1 | 31 | 2019 |
| 1 | 2 | 1 | 2019 |
| 2 | 2 | 2 | 2019 |
| 3 | 2 | 3 | 2019 |
| 4 | 2 | 4 | 2019 |
| 5 | 2 | 5 | 2019 |
| 6 | 2 | 6 | 2019 |
| 7 | 2 | 7 | 2019 |
| 8 | 2 | 8 | 2019 |
| 9 | 2 | 9 | 2019 |
| 10 | 2 | 10 | 2019 |
| 11 | 2 | 11 | 2019 |
| 12 | 2 | 12 | 2019 |
| 13 | 2 | 13 | 2019 |
| 14 | 2 | 14 | 2019 |
| 15 | 2 | 15 | 2019 |
| 16 | 2 | 16 | 2019 |
| 17 | 2 | 17 | 2019 |
+----+----------+----------+------+
How do I display data on the number of students for kelas 3 and kelas 5. on :
.$JUMLAH_SISWA.
For example Class 3 there are 17 students and Class 5 there are 14 Students
public function index() {
$d=array();
$ambil_data_kelas = $this->db->query("SELECT id, nama FROM m_kelas ORDER BY tingkat ASC, nama ASC")->result_array();
$tampil = "";
if (!empty($ambil_data_kelas)) {
foreach ($ambil_data_kelas as $v) {
$tampil .= '<div class="col-md-4"><div class="panel panel-info">
<div class="panel-heading"><b>'.$v['nama'].' jumlah siswa : '.$JUMLAH_SISWA.'</b></div>
<div class="panel-body" style="height: 300px; overflow: auto">
<table class="table table-stripped">
<thead>
<tr><th>No</th><th>Nama</th><th>Aksi</th></tr>
</thead>
<tbody>';
$q_siswa_per_kelas = $this->db->query("SELECT
a.id, b.nama nmsiswa, a.id_kelas
FROM t_kelas_siswa a
INNER JOIN m_siswa b ON a.id_siswa = b.id
WHERE a.id_kelas = '".$v['id']."'
AND a.ta = '".$this->d['ta']."'
ORDER BY b.nis ASC, b.nama ASC")->result_array();
if (!empty($q_siswa_per_kelas)) {
$no = 1;
foreach ($q_siswa_per_kelas as $k) {
$tampil .= '<tr><td>'.$no++.'</td><td>'.$k['nmsiswa'].'</td><td class="ctr"><i class="fa fa-remove"></i></td></tr>';
}
}
$tampil .= '</tbody></table></div></div></div>';
}
}
$this->d['tampil'] = $tampil;
$this->d['p'] = "list";
$this->load->view("template_utama", $this->d);
}
To count the number of students in each class you only need:
SELECT id_kelas, COUNT(*) 'count'
FROM kelas_siswa
GROUP BY id_kelas
and then you can bolt on additional JOINs to include whatever else you need like class metadata.
Eg:
SELECT ks.id_kelas, k.name, COUNT(*) 'count'
FROM kelas_siswa ks INNER JOIN kelas k
ON ks.id_kelas = k.id
GROUP BY ks.id_kelas
Or getting fancy:
SELECT ks.id_kelas, k.name, COUNT(*) 'count', GROUP_CONCAT(s.nama) 'students'
FROM kelas_siswa ks INNER JOIN kelas k
ON ks.id_kelas = k.id
INNER JOIN siswa s
ON ks.id_siswa = s.id
GROUP BY ks.id_kelas
Which will also list all the student names along with the count.
Related
I am generating sequential reference numbers like complaint/1, complaint/2 when an insertion is made. I get what the previously generated value is (complaint/2) and then increment.
But when two users submit at the same time, I sometimes get same reference nos for both complaints.
How do I prevent this?
SELECT RIGHT(Date_format(from_financial_year_,'%Y'),2),
RIGHT(Date_format(to_financial_year_,'%Y'),2)
INTO from_financial_year_,
to_financial_year_;SELECT rec.receipt_ref_no
INTO last_receipt_ref_num_
FROM svk_apt_receipts rec
WHERE Replace(Substring_index(rec.receipt_ref_no, '/', 2),'REC/','') = Concat(from_financial_year_,to_financial_year_)
AND rec.customer_id = customer_id_
AND rec.association_id = association_id_
ORDER BY rec.receipt_id DESC limit 1;IF(last_receipt_ref_num_ IS NULL) then
SELECT 1
INTO max_ref_id_;
else
SELECT (replace(last_receipt_ref_num_, concat('REC/',from_financial_year_,to_financial_year_,'/'),'')+1)
INTO max_ref_id_;ENDIF;SELECT Concat('REC/',from_financial_year_,to_financial_year_,'/',max_ref_id_)
INTO receipt_ref_no_;INSERT INTO svk_apt_receipts
(
receipt_ref_no, paid, payable, is_paid, master_receipt_to_id, receipt_from_id, receipt_to_id, receipt_date,
receipt_mode, transaction_ref_no, customer_id, association_id, is_active, created_by, created_on, receipt_status_id, remarks
)
VALUES
( receipt_ref_no_, _total_amount, 0,1,3, receipt_from_id_, receipt_to_id_, Cast(Now()AS DATE), 3, _transaction_ref_no,
customer_id_, association_id_, 1, _created_by, Now(), 2, 'Paid through Payment Gateway'
);
As mentioned in comments, just store an autoincrementing id. All the other stuff can be handled by trivial queries and/or your presentation layer.
By way of example...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,user INT NOT NULL
);
INSERT INTO my_table (user) VALUES
(1),(1),(3),(3),(5),(2),(1),(8),(4),(5),(7),(5),(5),(4),(1),(2),(3),(6),(4),(6),(1),(5),(1),(8);
SELECT * FROM my_table;
+----+------+
| id | user |
+----+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 3 |
| 4 | 3 |
| 5 | 5 |
| 6 | 2 |
| 7 | 1 |
| 8 | 8 |
| 9 | 4 |
| 10 | 5 |
| 11 | 7 |
| 12 | 5 |
| 13 | 5 |
| 14 | 4 |
| 15 | 1 |
| 16 | 2 |
| 17 | 3 |
| 18 | 6 |
| 19 | 4 |
| 20 | 6 |
| 21 | 1 |
| 22 | 5 |
| 23 | 1 |
| 24 | 8 |
+----+------+
24 rows in set (0.01 sec)
SELECT x.*
, COUNT(*) complaint
FROM my_table x
JOIN my_table y
ON y.user = x.user
AND y.id <= x.id
GROUP
BY x.id
ORDER
BY user
, id;
+----+------+-----------+
| id | user | complaint |
+----+------+-----------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 7 | 1 | 3 |
| 15 | 1 | 4 |
| 21 | 1 | 5 |
| 23 | 1 | 6 |
| 6 | 2 | 1 |
| 16 | 2 | 2 |
| 3 | 3 | 1 |
| 4 | 3 | 2 |
| 17 | 3 | 3 |
| 9 | 4 | 1 |
| 14 | 4 | 2 |
| 19 | 4 | 3 |
| 5 | 5 | 1 |
| 10 | 5 | 2 |
| 12 | 5 | 3 |
| 13 | 5 | 4 |
| 22 | 5 | 5 |
| 18 | 6 | 1 |
| 20 | 6 | 2 |
| 11 | 7 | 1 |
| 8 | 8 | 1 |
| 24 | 8 | 2 |
+----+------+-----------+
24 rows in set (0.00 sec)
so I was able to build a Morris chart following some tutorials, and this is what I've come up with so far
$range = \Carbon\Carbon::now()->subDays(30);
$stats = DB::table('tickets')
->where('created_at', '>=', $range)
->groupBy('date')
->orderBy('date', 'ASC')
->get([
DB::raw('Date(created_at) as date'),
DB::raw('COUNT(*) as value')
])
->toJSON();
OUTPUT
"[{"date":"2018-11-10","value":1},{"date":"2018-11-11","value":1}]"
the thing is I'm trying to get the results by months and ticket status not daily.
js code
Morris.Area({
element: 'morris-area-chart'
, data: data
, xkey: 'date'
, ykeys: ['status']
});
Tickets Table
id|phone_model |cus_name |issue |notes |created_at |updated_at |status
Expected Output
[{"date":"11","tickets":2,"status":1},{"date":"11","tickets":1,"status":2},
{"date":"10","tickets":3,"status":1},{"date":"10","tickets":1,"status":3},]
I tried more than a way to get the results based on months and ticket status but no luck
any help will be appreciated, Thank you.
You can use this query:
$result_arr = \DB::select("SELECT DATE_FORMAT(created_at, '%m') date, status, COUNT(*) count FROM tickets GROUP BY date, status ORDER BY date DESC");
return collect($result_arr)->toJson();
It outputs such a result for example(Output is in mysql console here):
+------+--------+-------+
| date | status | count |
+------+--------+-------+
| 12 | 1 | 1 |
| 12 | 2 | 3 |
| 12 | 4 | 1 |
| 12 | 10 | 7 |
| 11 | 1 | 1 |
| 11 | 2 | 1 |
| 11 | 4 | 1 |
| 10 | 1 | 3 |
| 10 | 2 | 2 |
| 10 | 3 | 1 |
| 10 | 4 | 2 |
| 09 | 1 | 2 |
| 09 | 2 | 7 |
| 09 | 3 | 5 |
| 08 | 1 | 1 |
| 08 | 2 | 1 |
| 08 | 12 | 1 |
| 07 | 1 | 4 |
| 06 | 1 | 1 |
| 06 | 2 | 12 |
| 06 | 3 | 2 |
| 05 | 1 | 1 |
| 05 | 2 | 8 |
| 05 | 11 | 1 |
| 04 | 1 | 2 |
| 04 | 2 | 8 |
| 04 | 10 | 1 |
| 03 | 1 | 2 |
| 02 | 1 | 2 |
| 02 | 2 | 26 |
| 02 | 3 | 1 |
| 02 | 11 | 2 |
| 02 | 12 | 1 |
| 01 | 2 | 21 |
| 01 | 3 | 8 |
| 01 | 10 | 6 |
+------+--------+-------+
36 rows in set (0.00 sec)
Keep in mind that as you want to group the results based on both status & date it does not give you just a row for each date(as you may have multiple statuses), so for each date you may have different values for each status.
See Mysql Docs for more about DATE_FORMAT.
I have a table like this
+----+--------+--------+
| id | ref_id | status |
+----+--------+--------+
| 1 | 3 | 1 |
| 2 | 4 | 0 |
| 4 | 6 | 0 |
| 6 | 8 | 1 |
| 8 | 10 | 0 |
| 10 | 12 | 1 |
| 12 | 14 | 1 |
| 14 | 16 | 0 |
| 16 | 18 | 0 |
| 18 | 20 | 0 |
+----+--------+--------+
I want to find the number of rows that has a status 0 in descending order continuously. In this Case number would be 3
+----+--------+--------+
| id | ref_id | status |
+----+--------+--------+
| 1 | 3 | 1 |
| 2 | 4 | 0 |
| 4 | 6 | 0 |
| 6 | 8 | 1 |
| 8 | 10 | 1 |
| 10 | 12 | 1 |
| 12 | 14 | 0 |
| 14 | 16 | 0 |
| 16 | 18 | 0 |
| 18 | 20 | 0 |
+----+--------+--------+
In this case it is four
+----+--------+--------+
| id | ref_id | status |
+----+--------+--------+
| 1 | 3 | 1 |
| 2 | 4 | 0 |
| 4 | 6 | 0 |
| 6 | 8 | 1 |
| 8 | 10 | 1 |
| 10 | 12 | 1 |
| 12 | 14 | 0 |
| 14 | 16 | 0 |
| 16 | 18 | 0 |
| 18 | 20 | 1 |
+----+--------+--------+
In this case it is 0
So far I tried is processing the rows descending and finding it through php condition . Is there any better way to do it ?
I used this code in codeigniter and get the result
$this->db->select('count(id) as number');
$this->db->from('tablename');
$this->db->where('id > (select max(id) FROM tablename where status = 1)',
NULL, FALSE);
In mysql
SELECT count(id) as number FROM tablename
WHERE id > (select max(id) FROM tablename where status = 1)
I have 2 tables which I need to join and sum the qty based on a requirement. Here's the tables structure.
Customer
---------------------------------------------------
ID | Name | Tel | Sex
---------------------------------------------------
1 | John | 123 XXXX | M
2 | Peter | 456 XXXX | M
3 | Alice | 789 XXXX | F
4 | Amy | 147 XXXX | F
Transaction
---------------------------------------------------
ID | CustID | TranID | Books | Pens | Rulers
---------------------------------------------------
1 | 1 | Jan | 1 | 1 | 0
2 | 1 | Feb | 1 | 0 | 0
3 | 2 | Jan | 1 | 0 | 1
4 | 2 | Jan | 1 | 0 | 0
5 | 3 | Feb | 0 | 1 | 1
6 | 4 | Feb | 1 | 1 | 0
7 | 3 | Feb | 1 | 1 | 0
8 | 4 | Feb | 0 | 0 | 1
9 | 3 | Jan | 1 | 0 | 0
10 | 2 | Jan | 1 | 1 | 0
Required Results (Sex=F, TranID=Jan, Sum:Books, Pens & Rulers)
--------------------------------------------------------------
Name | Tel | Sex | B.TOT | P.TOT | R.TOT
--------------------------------------------------------------
Alice | 789 XXXX | F | 1 | 0 | 0
Amy | 147 XXXX | F | 0 | 0 | 0
I've tried with the following SQL statement and it is working as long as the Transaction Table is NOT EMPTY.
select
`customer`.name,
`customer`.tel,
`customer`.sex,
sum(if(`transaction`.TranID = 'JAN',books,0)) as B.Tot,
sum(if(`transaction`.TranID = 'JAN',pens,0)) as P.Tot,
sum(if(`transaction`.TranID = 'JAN',rulers,0)) as R.tot,
from
`customer`
left join
`transaction`
on
`customer`.id = `transaction`.custid
where
`customer`.sex = 'F'
Group by
`customer`.id,
order by
`customer`.name ASC
How do I modify the above to show the Customer List where SEX='F' even the transaction table is totally empty?
SQL QUERY
I hope this query will resolve your problem :
SELECT
c.name,
c.tel,
c.sex,
IFNULL(SUM(t.books), 0) 'B.TOT',
IFNULL(SUM(t.pens), 0) 'P.TOT',
IFNULL(SUM(t.rulers), 0) 'R.TOT'
FROM
customer c
LEFT JOIN
`transaction` t ON t.custid = c.id AND t.TranID = 'Jan'
WHERE
c.sex = 'F'
GROUP BY c.id
ORDER BY c.name;
I have 4 table for my Ads Portal.
Firstly main table name is ads
+-------------+
| Field +
+-------------+
| id +
| ads_title +
+-------------+
example data for ads table;
+----+-----------------+
| id | ads_title |
+----+-----------------+
| 20 | 2006 CITROEN C4 |
| 27 | EMEKLI OGRETMEN |
| 28 | Harika 10 n |
| 34 | HATASIZ BOYASIZ |
| 49 | BAYANDAN 2009 |
+----+-----------------+
for ads specifications stored in a table. table name is ads_spc
+---------+
| Field |
+---------+
| id |
| key_name|
+---------+
data example for ads_spc table;
+----+-------------+
| id | key_name |
+----+-------------+
| 1 | Date |
| 2 | Km |
| 3 | Colr |
| 4 | Engine |
| 5 | Pw. Engine |
| 6 | Oil |
| 7 | Speed |
| 8 | Boody Type |
| 9 | Traction |
| 10 | Warranty |
+----+-------------+
Lastly stored specification values for ads_spc by ads_id. table name is ads_values
+------------+
| Field |
+------------+
| id |
| ads_id |
| spc_id |
| value |
+------------+
for example this table data
+----+--------+--------+-------+
| id | ads_id | spc_id | value |
+----+--------+--------+-------+
| 25 | 49 | 9 | 2119 |
| 26 | 49 | 10 | 2131 |
| 27 | 34 | 1 | 2010 |
| 28 | 34 | 2 | 8900 |
| 29 | 34 | 3 | 4 |
| 30 | 34 | 4 | 22 |
| 31 | 34 | 5 | 40 |
| 32 | 34 | 6 | 60 |
| 33 | 34 | 7 | 65 |
| 34 | 34 | 8 | 66 |
+----+--------+--------+-------+
I want to using these tables list ads (table: ads) with specifications (table:ads_spc) and ads values (table:ads_values) in a data row.
Union to;
ADS + ADS_SPC + ADS_VALUES (All values searchable)
I'm using this case:
SELECT SQL_CALC_FOUND_ROWS
*
FROM ads AS a
LEFT JOIN ads_spc AS aspc
LEFT JOIN ads_values AS aval ON aval.ads_id=a.id AND aval.spc_id=aspc.spc_id
How can I union to one row?
Sorry for my english.
Why union there is no sense for the union you should join these tables
SELECT v.id, a.ads_title,s.key_name,v.value FROM `ads` a
INNER JOIN `ads_values` v ON (a.id =v.ads_id)
INNER JOIN `ads_spc` s ON(v.spc_id =s.id) WHERE s.key_name='Color'