Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Hỗ trợ truy vấn SQL có điều kiện

Những câu hỏi ngắn và đơn giản có xu hướng thu hút nhiều sự chú ý hơn những câu dài / phức tạp. Điều này không phải vì chúng tôi không thể trả lời mà là do có quá nhiều câu hỏi và quá ít thời gian dành cho tình nguyện viên, thật khó để có đủ thời gian để đọc những câu hỏi lớn.

Tuy nhiên, tôi nghĩ rằng yêu cầu cơ bản của bạn không quá phức tạp. Bạn muốn một cách để truy xuất các hàng nằm trong phạm vi thời gian HOẶC nếu không nằm trong phạm vi đó, hãy cung cấp các hàng gần nhất với phạm vi đó.

Trong cơ sở dữ liệu hỗ trợ ROW_NUMBER () OVER () điều này khá dễ dàng (và MySQL 8.x được lên kế hoạch hỗ trợ điều này), nhưng cho đến thời điểm đó để mô phỏng row_number (), bạn có thể sử dụng các biến và một truy vấn con có thứ tự.

Bạn có thể dùng thử giải pháp này tại đây SQL Fiddle

Thiết lập lược đồ 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);

Truy vấn :

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)

Vì vậy, những gì điều này làm là tính toán một "RowNumber" bắt đầu từ 1 cho hàng gần đây nhất cho mỗi bảng nguồn. Sau đó, bảng dẫn xuất này được lọc theo phạm vi thời gian hoặc theo số hàng nếu không nằm trong phạm vi thời gian.

Cũng xin lưu ý rằng tôi đã KHÔNG sử dụng UNION nhưng thay vào đó đã sử dụng UNION ALL . Có sự khác biệt lớn về hiệu suất và nên học cách sử dụng từng loại tùy theo nhu cầu. Nếu sử dụng UNION cũng không sử dụng select distinct bởi vì bạn chỉ đang lãng phí nỗ lực.

Kết quả :

|     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. mySQL DataSource trên Visual Studio 2012

  2. Codeigniter, Join và Case When Query

  3. ĐỌC và VIẾT đồng thời trên Bảng MySQL

  4. Cách INNER THAM GIA 3 bảng bằng CodeIgniter

  5. Mysql chọn danh sách sau một id cụ thể