使用 NOT IN 而不是 CTE 或临时表

问题描述

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.drawing2d;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    namespace generateFonts
    {
        public partial class Form1 : Form
        {
            string font = "";
            float fontSize = 0;
            FontStyle fontStyle = FontStyle.Regular;

            public Form1()
            {
                InitializeComponent();
                comboBox1.Selectedindex = 0;
                comboBox2.Selectedindex = 0;
                comboBox3.Selectedindex = 0;

                font = comboBox1.SelectedItem.ToString();
                fontSize = Convert.ToInt32(comboBox2.SelectedItem);
                fontStyle = FontStyle.Regular;
            }

            private void comboBox1_SelectedindexChanged(object sender,EventArgs e)
            {
                font = comboBox1.SelectedItem.ToString();
            }

            private void comboBox2_SelectedindexChanged(object sender,EventArgs e)
            {
                fontSize = Convert.ToInt32(comboBox2.SelectedItem);
            }

            private void comboBox3_SelectedindexChanged(object sender,EventArgs e)
            {
                if (comboBox3.Selectedindex == 0)
                    fontStyle = FontStyle.Regular;
                else if (comboBox3.Selectedindex == 1)
                    fontStyle = FontStyle.Italic;
                else if(comboBox3.Selectedindex == 2)
                    fontStyle = FontStyle.Bold;
            }

            private async void button1_Click(object sender,EventArgs e)
            {
                await Task.Run(() => StartProcess(1));
            }

            private void StartProcess(int runs)
            {
                // Font 
                Font myFont = new Font(font,fontSize,fontStyle);

                List<string> bytes = new List<string>();

                string[] bits = { "0","0","0" };
                byte bitPos = 0;

                for (byte i = 32; i < 126; i++)
                {
                    //Create a Image-Object on which we can paint
                    Image bmp = new Bitmap(200,200);

                    //Create the Graphics-Object to paint on the Bitmap
                    Graphics g = Graphics.FromImage(bmp);

                    string c = Convert.tochar(i).ToString();

                    //Get the perfect Image-Size so that Image-Size = String-Size
                    Sizef size = g.MeasureString(c,myFont);

                    //Use this to become better Text-Quality on Bitmap.
                    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;

                    //Here we draw the string on the Bitmap
                    g.DrawString(c,myFont,new SolidBrush(Color.Black),0);

                    if (!Directory.Exists("FontBmps"))
                        Directory.CreateDirectory("FontBmps");

                    this.Invoke((MethodInvoker)delegate ()
                    {
                        pictureBox2.Width = Convert.ToInt32(size.Width);
                        pictureBox2.Height = Convert.ToInt32(size.Height);
                        pictureBox2.Image = bmp; // <--- this is working and the pictureBox shows the bmp correctly
                        bmp.Save("FontBmps/" + i + "_" + font + "_" + fontSize + "px_" + fontStyle + ".bmp",ImageFormat.Bmp); // <--- error here: this saves a black square instead of the bmp i see displayed in the pictureBox GUI ??
                        // Even if i save the pictureBox itself that too is just a black square instead of the correct image shown in the GUI ??

                        // Now convert the bmp to a HEX array of pixels
                        for (int h = 0; h < pictureBox2.Height; h++)
                        {
                            for (int w = 0; w < pictureBox2.Width; w++)
                            {
                                Color colour = (pictureBox2.Image as Bitmap).GetPixel(w,h);

                                if (colour.R == 0 && colour.G == 0 && colour.B == 0)
                                {
                                    bits[bitPos] = "1";
                                }
                                else
                                {
                                    bits[bitPos] = "0"; // <-- never hits me,again for some reason the bmp or pictureBox is all black pixels data but i see it correctly show in the pictureBox GUI ??
                                }

                                if (bitPos < 7)
                                    bitPos++;
                                else
                                {
                                    //string bitStr = bits.ToString();
                                    //string hex = Convert.ToByte(bitStr,2).ToString("x2");
                                    //bytes.Add(hex);
                                    bitPos = 0;
                                    for(byte n = 0; n < 8; n++)
                                    {
                                        bits[n] = "0";
                                    }
                                }

                            }
                        }

                        if (bitPos != 0)
                        {
                            // TO DO...
                        }

                    });
                    Thread.Sleep(500); // <--- i have this just to see it displaying the chars but i have removed it with no effect to the issue 
                }
                // Now add List to a file in the correct format
                foreach (string str in bytes)
                {
                    Console.WriteLine(str);
                    // TO DO...
                }
            }


        }
    }

所以我想在 sql 中使用 select distinct patientID from [dbo]..HPrecords where ptprocess = 'refill' and pTDescription <> 'Success' and patientID is not null and patiententrytime > '2021-04-06' and patientID not in ( select distinct patientID from [dbo]..HPrecords where ptprocess = 'embossing' and ptDescription = 'Success' and patientID is not null and patiententrytime > '2021-04-06' ) 功能来过滤出尚未收到补充药物的患者。一个病人可以多次补充,第一次可能会失败,但第二次或第三次可能会成功。所以可以有多行。

所以我只想编写一个查询,该查询将过滤掉并为我获取无论多少次都没有成功重新填充的患者 ID。

这是最好的写法吗,我当前的查询还在运行,我觉得逻辑不对?

我想尝试在没有 CTE 或临时表的情况下编写此查询,作为练习。

示例输出

NOT IN

解决方法

我个人更喜欢加入而不是加入。看起来更整洁,读起来更好,并且如果您需要分析异常,则允许访问两个表上的信息。我和一位同事曾经做过一些非常基本的性能比较,并没有显着差异。

这是我的看法..

select  distinct hpr.patientID
from    [dbo].HPrecords hpr
        LEFT OUTER JOIN
            [dbo].HPrecords hpr_val ON
                hpr.patientID = hpr_val.patientID
                AND hpr_val.ptprocess = 'embossing'
                AND hpr_val.ptDescription = 'Success'
                and hpr_val.patiententrytime > '20`enter code here`21-04-06'
where   hpr.ptprocess = 'refill'
and     hpr.pTDescription <> 'Success'
--and       hpr.patientID is not null  -- Not necessary because you will always have records in this table in this scenario
and     hpr.patiententrytime > '2021-04-06'
AND     hpr_Val.PatietID IS NULL

在模式和表名之间的额外点上......正如 Smor 指出的那样,它没有必要(甚至可能会破坏查询),而是在指向数据库时不想引用模式时使用和桌子。

  • 长路漫漫:[database].[schema].[table] -- 示例 [MyDatabase].[dbo].[MyTable]
  • 捷径:[database]..[table] -- 示例 [MyDatabase]..[MyTable]