Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Bantuan Kueri SQL Bersyarat

Pertanyaan pendek dan sederhana cenderung mendapat perhatian lebih daripada pertanyaan panjang/kompleks. Ini bukan karena kami tidak dapat menjawab tetapi dengan begitu banyak pertanyaan, dan begitu sedikit waktu sukarela yang diberikan, sulit untuk membenarkan waktu untuk membaca pertanyaan-pertanyaan besar.

Namun saya pikir kebutuhan dasar Anda tidak terlalu rumit. Anda menginginkan cara untuk mengambil baris yang berada dalam rentang waktu ATAU jika tidak dalam rentang tersebut, berikan baris terdekat dengan rentang tersebut.

Dalam database yang mendukung ROW_NUMBER() OVER() ini cukup mudah (dan MySQL 8.x direncanakan untuk mendukung ini), tetapi sampai saat itu untuk meniru row_number() Anda dapat menggunakan variabel dan subquery yang dipesan.

Anda dapat mencoba solusi ini di SQL Fiddle

Pengaturan Skema MySQL 5.6 :

CREATE TABLE `ponumber` (
  `TimeStr` datetime NOT NULL,
  `Value` int(11) NOT NULL,
  UNIQUE KEY `uk_Times` (`TimeStr`));

INSERT INTO `PONumber`     (`TimeStr`,`Value`) VALUES ('2017-09-28 10:47:55',0);
INSERT INTO `PONumber`     (`TimeStr`,`Value`) VALUES ('2017-09-28 06:26:07',1217911);
INSERT INTO `PONumber`     (`TimeStr`,`Value`) VALUES ('2017-09-28 05:24:18',1217906);

CREATE TABLE `batch_number` (
  `TimeStr` datetime NOT NULL,
  `Value` int(11) NOT NULL,
  UNIQUE KEY `uk_Times` (`TimeStr`));

INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-29 12:46:18',5522);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-29 12:25:33',5521);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-29 11:44:45',5520);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-28 06:26:05',5519);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-28 05:22:58',5518);

CREATE TABLE `batchweight` (
  `TimeStr` datetime NOT NULL,
  `Value` int(11) NOT NULL,
  UNIQUE KEY `uk_Times` (`TimeStr`));

INSERT INTO `batchweight`  (`TimeStr`,`Value`) VALUES ('2017-09-29 12:46:19',38985);
INSERT INTO `batchweight`  (`TimeStr`,`Value`) VALUES ('2017-09-28 06:26:07',38985);
INSERT INTO `batchweight`  (`TimeStr`,`Value`) VALUES ('2017-09-28 05:23:03',31002);

Kueri :

SET @bStartTime  := '2017-09-29 11:10:00'   
SET @bEndTime    := '2017-09-29 12:48:00'

SELECT 
      SrcTable, TimeStr, Value
FROM (
      SELECT
            @row_num :=IF( @prev_value=u.SrcTable, @row_num + 1 ,1) AS RowNumber
          , u.*
          , @prev_value := u.SrcTable
      FROM (

          select 'ponumber' SrcTable , TimeStr, `Value`
          from ponumber
          union all
          select 'batch_number' SrcTable , TimeStr, `Value`
          from batch_number
          union all
          select 'batchweight' SrcTable , TimeStr, `Value`
          from batchweight
          ) u
      CROSS JOIN (SELECT @row_num := 1,  @prev_value :='') vars
      ORDER BY SrcTable, TimeStr DESC
      ) d
WHERE (d.TimeStr between @bStartTime and @bEndTime)
   OR (TimeStr < @bStartTime AND RowNumber = 1)

Jadi, yang dilakukan adalah menghitung "RowNumber" yang dimulai dari 1 untuk baris terbaru untuk setiap tabel sumber. Kemudian tabel turunan ini difilter menurut rentang waktu, atau menurut nomor baris jika tidak berada dalam rentang waktu tersebut.

Perhatikan juga bahwa saya TIDAK menggunakan UNION tetapi sebaliknya telah menggunakan UNION ALL . Ada perbedaan besar dalam kinerja dan harus belajar menggunakan masing-masing sesuai kebutuhan. Jika menggunakan UNION jangan juga menggunakan select distinct karena Anda hanya membuang-buang usaha.

Hasil :

|     SrcTable |              TimeStr | Value |
|--------------|----------------------|-------|
|  batchweight | 2017-09-29T12:46:19Z | 38985 |
| batch_number | 2017-09-29T12:46:18Z |  5522 |
| batch_number | 2017-09-29T12:25:33Z |  5521 |
| batch_number | 2017-09-29T11:44:45Z |  5520 |
|     ponumber | 2017-09-28T10:47:55Z |     0 |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL-alchemy:ValueError terlalu banyak nilai untuk dibongkar?

  2. SQL:dapatkan item ke-N di setiap grup

  3. Bagaimana cara membuang sewenang-wenang di MySQL?

  4. Memilih frekuensi hasil yang dapat muncul di beberapa kolom (SQL)

  5. Bagaimana saya bisa mengatur format peningkatan otomatis ke 0001 di MySQL?